agentic-api 2.0.684 → 2.0.885
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/dist/src/agents/prompts.d.ts +2 -3
- package/dist/src/agents/prompts.js +13 -109
- package/dist/src/agents/reducer.loaders.d.ts +46 -15
- package/dist/src/agents/reducer.loaders.js +76 -21
- package/dist/src/agents/reducer.types.d.ts +30 -3
- package/dist/src/agents/simulator.d.ts +3 -2
- package/dist/src/agents/simulator.executor.d.ts +8 -2
- package/dist/src/agents/simulator.executor.js +62 -26
- package/dist/src/agents/simulator.js +100 -11
- package/dist/src/agents/simulator.prompts.d.ts +48 -21
- package/dist/src/agents/simulator.prompts.js +289 -122
- package/dist/src/agents/simulator.types.d.ts +33 -1
- package/dist/src/agents/subagent.d.ts +128 -0
- package/dist/src/agents/subagent.js +231 -0
- package/dist/src/agents/worker.executor.d.ts +48 -0
- package/dist/src/agents/worker.executor.js +152 -0
- package/dist/src/execute/helpers.d.ts +3 -0
- package/dist/src/execute/helpers.js +221 -15
- package/dist/src/execute/responses.js +78 -51
- package/dist/src/execute/shared.d.ts +5 -0
- package/dist/src/execute/shared.js +27 -0
- package/dist/src/index.d.ts +2 -1
- package/dist/src/index.js +3 -1
- package/dist/src/llm/openai.js +8 -1
- package/dist/src/llm/pricing.js +2 -0
- package/dist/src/llm/xai.js +11 -6
- package/dist/src/prompts.d.ts +14 -0
- package/dist/src/prompts.js +41 -1
- package/dist/src/rag/rag.manager.d.ts +18 -3
- package/dist/src/rag/rag.manager.js +91 -5
- package/dist/src/rules/git/git.e2e.helper.js +3 -0
- package/dist/src/rules/git/git.health.js +88 -57
- package/dist/src/rules/git/index.d.ts +1 -1
- package/dist/src/rules/git/index.js +13 -5
- package/dist/src/rules/git/repo.d.ts +25 -6
- package/dist/src/rules/git/repo.js +430 -146
- package/dist/src/rules/git/repo.pr.js +45 -13
- package/dist/src/rules/git/repo.tools.d.ts +5 -0
- package/dist/src/rules/git/repo.tools.js +6 -1
- package/dist/src/rules/types.d.ts +0 -2
- package/dist/src/rules/utils.matter.js +1 -5
- package/dist/src/scrapper.d.ts +138 -25
- package/dist/src/scrapper.js +538 -160
- package/dist/src/stategraph/stategraph.d.ts +4 -0
- package/dist/src/stategraph/stategraph.js +16 -0
- package/dist/src/stategraph/types.d.ts +13 -1
- package/dist/src/types.d.ts +21 -0
- package/dist/src/utils.d.ts +24 -0
- package/dist/src/utils.js +84 -86
- package/package.json +3 -2
- package/dist/src/agents/semantic.d.ts +0 -4
- package/dist/src/agents/semantic.js +0 -19
- package/dist/src/execute/legacy.d.ts +0 -46
- package/dist/src/execute/legacy.js +0 -460
- package/dist/src/pricing.llm.d.ts +0 -5
- package/dist/src/pricing.llm.js +0 -14
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.AgentExecutor = void 0;
|
|
4
|
+
exports.buildExecutionContextTag = buildExecutionContextTag;
|
|
5
|
+
const utils_1 = require("../utils");
|
|
4
6
|
const rag_1 = require("../rag");
|
|
5
7
|
const stategraph_1 = require("../stategraph");
|
|
6
8
|
const execute_1 = require("../execute");
|
|
@@ -16,7 +18,7 @@ class AgentExecutor {
|
|
|
16
18
|
// - Mode worker : collaborateur avec WORKER_INTERNAL_PROMPT
|
|
17
19
|
this.simulatorAgentBase = {
|
|
18
20
|
name: this.isWorkerMode ? simulator_types_1.WORKER_AGENT_NAME : simulator_types_1.SIMULATOR_AGENT_NAME,
|
|
19
|
-
model: ('HIGH-fast'),
|
|
21
|
+
model: (config.workerModel || 'HIGH-fast'),
|
|
20
22
|
publicDescription: this.isWorkerMode ? simulator_types_1.WORKER_AGENT_DESCRIPTION : simulator_types_1.SIMULATOR_AGENT_DESCRIPTION,
|
|
21
23
|
cancelMemory: true,
|
|
22
24
|
instructions: '', // Sera construit dans initializeContexts
|
|
@@ -24,11 +26,35 @@ class AgentExecutor {
|
|
|
24
26
|
downstreamAgents: []
|
|
25
27
|
};
|
|
26
28
|
//
|
|
27
|
-
//
|
|
28
|
-
//
|
|
29
|
-
|
|
29
|
+
// DANGER: sans ce filtre, le Worker appelle createWorkerJob en boucle
|
|
30
|
+
// récursive (33 jobs créés en <1s, crash sur la limite de 20).
|
|
31
|
+
// IMPORTANT: cloner les agents pour ne pas muter l'original (singleton _defaultAgent)
|
|
32
|
+
// FIXME: remplacer par une construction dynamique du périmètre tools
|
|
33
|
+
// (ex: excludeTools sur AgentConfig, lu par injectTransferTools)
|
|
34
|
+
const EXCLUDES_TOOLS = ['searchNoteMemories', 'updateUserMemory', 'createWorkerJob', 'createTaskListJob', 'sendFeedbackEmail'];
|
|
35
|
+
// const JOB_TOOLS = ['createWorkerJob', 'createTaskListJob'];
|
|
36
|
+
config.agents = config.agents.map(agent => ({
|
|
37
|
+
...agent,
|
|
38
|
+
tools: agent.tools ? [...agent.tools] : [],
|
|
39
|
+
//
|
|
40
|
+
// Override du modèle de l'agent piloté si spécifié
|
|
41
|
+
...(this.isWorkerMode && config.agentModel ? { model: config.agentModel } : {})
|
|
42
|
+
}));
|
|
43
|
+
if (this.isWorkerMode) {
|
|
44
|
+
//
|
|
45
|
+
// Mode worker : supprimer les tools de création de jobs (anti-récursion)
|
|
46
|
+
// et les tools mémoire (réservés aux interactions directes utilisateur)
|
|
47
|
+
const excludeWorker = [...EXCLUDES_TOOLS];
|
|
48
|
+
config.agents.forEach(agent => {
|
|
49
|
+
agent.tools = agent.tools.filter(t => !excludeWorker.includes(t.function?.name));
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
//
|
|
54
|
+
// Mode simulator : supprimer les tools mémoire des agents en test
|
|
30
55
|
config.agents.forEach(agent => {
|
|
31
56
|
agent.cancelMemory = true;
|
|
57
|
+
agent.tools = agent.tools.filter(t => !EXCLUDES_TOOLS.includes(t.function?.name));
|
|
32
58
|
});
|
|
33
59
|
}
|
|
34
60
|
//
|
|
@@ -59,7 +85,7 @@ class AgentExecutor {
|
|
|
59
85
|
const agentContext = (this.isWorkerMode && externalAgentContext)
|
|
60
86
|
? externalAgentContext
|
|
61
87
|
: {
|
|
62
|
-
user: { id: `test-user`, role: 'user', uid: `test-${sessionId}` },
|
|
88
|
+
user: { id: `test-user`, role: 'user', uid: `test-${sessionId}`, mail: `test-${sessionId}@simulator.local` },
|
|
63
89
|
credential: { test: true, sessionId: `agent-${sessionId}` },
|
|
64
90
|
verbose: this.config.verbose,
|
|
65
91
|
session: { id: `agent-${sessionId}`, data: {}, messages: [] },
|
|
@@ -80,11 +106,11 @@ class AgentExecutor {
|
|
|
80
106
|
}
|
|
81
107
|
//
|
|
82
108
|
// Construire les instructions selon le mode
|
|
83
|
-
// - Simulator : GENERIC_SIMULATOR_PROMPT(scenario) +
|
|
84
|
-
// - Worker : WORKER_INTERNAL_PROMPT(
|
|
109
|
+
// - Simulator : GENERIC_SIMULATOR_PROMPT(scenario) + positionDescription
|
|
110
|
+
// - Worker : WORKER_INTERNAL_PROMPT(positionDescription + personaResult)
|
|
85
111
|
const fullInstructions = this.isWorkerMode
|
|
86
|
-
? (0, simulator_prompts_1.WORKER_INTERNAL_PROMPT)(this.config.
|
|
87
|
-
: (0, simulator_prompts_1.GENERIC_SIMULATOR_PROMPT)(scenario, this.config.
|
|
112
|
+
? (0, simulator_prompts_1.WORKER_INTERNAL_PROMPT)(this.config.positionDescription || '', this.config.personaResult, (0, utils_1.extractAgentCapabilities)(this.config.agents, this.config.start))
|
|
113
|
+
: (0, simulator_prompts_1.GENERIC_SIMULATOR_PROMPT)(scenario, this.config.positionDescription);
|
|
88
114
|
return {
|
|
89
115
|
agentContext,
|
|
90
116
|
simulatorContext: orchestratorContext,
|
|
@@ -107,9 +133,13 @@ class AgentExecutor {
|
|
|
107
133
|
* ✅ Exécuter l'agent testé et retourner sa réponse (extraction de agent-vs-agent.ts)
|
|
108
134
|
*/
|
|
109
135
|
async executeAgent(context, query) {
|
|
136
|
+
//
|
|
137
|
+
// Mode worker uniquement : signaler à l'Agent qu'il est piloté par un orchestrateur
|
|
138
|
+
// afin d'éviter les questions de clarification sans réponse possible
|
|
139
|
+
const finalQuery = this.isWorkerMode ? simulator_prompts_1.WORKER_AUTONOMOUS_PREFIX + query : query;
|
|
110
140
|
// Logique extraite de AgentVsAgentTester.executeAgentWithContext()
|
|
111
141
|
const execResult = await (0, execute_1.executeAgentSet)(this.config.agents, context.agentContext, {
|
|
112
|
-
query,
|
|
142
|
+
query: finalQuery,
|
|
113
143
|
home: this.config.start,
|
|
114
144
|
stdout: execute_1.DummyWritable,
|
|
115
145
|
verbose: this.config.verbose,
|
|
@@ -150,7 +180,7 @@ class AgentExecutor {
|
|
|
150
180
|
// ✅ Injecter le contexte technique si disponible
|
|
151
181
|
const agentContextInjection = this.buildAgentContextInjection(context);
|
|
152
182
|
const enrichedQuery = agentContextInjection ? `${query}\n\n${agentContextInjection}` : query;
|
|
153
|
-
// console.log('
|
|
183
|
+
// console.log(`📡 Simulator input (turn ${context.exchangeCount}/${context.maxTurns || '?'}):\n query[${enrichedQuery.length}]: ${enrichedQuery.substring(0, 200)}${enrichedQuery.length > 200 ? '...' : ''}\n context: ${agentContextInjection.substring(0, 120)}`);
|
|
154
184
|
await (0, execute_1.executeAgentSet)([context.simulatorAgent], context.simulatorContext, {
|
|
155
185
|
query: enrichedQuery,
|
|
156
186
|
home: this.isWorkerMode ? simulator_types_1.WORKER_AGENT_NAME : simulator_types_1.SIMULATOR_AGENT_NAME,
|
|
@@ -159,27 +189,16 @@ class AgentExecutor {
|
|
|
159
189
|
debug: false
|
|
160
190
|
});
|
|
161
191
|
const response = this.getLastAssistantMessage(context.simulatorContext);
|
|
192
|
+
// console.log(`📡 Simulator output (turn ${context.exchangeCount}): ${response.substring(0, 200)}${response.length > 200 ? '...' : ''}`);
|
|
162
193
|
context.conversationHistory.push(`Simulator: ${response}`);
|
|
163
194
|
return response;
|
|
164
195
|
}
|
|
165
196
|
/**
|
|
166
|
-
*
|
|
167
|
-
* Permet au simulateur de connaître les tools utilisés par l'agent testé
|
|
197
|
+
* Construire l'injection de contexte à chaque tour
|
|
168
198
|
*/
|
|
169
199
|
buildAgentContextInjection(context) {
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
}
|
|
173
|
-
// Extraire les noms des tools appelés (sans les arguments)
|
|
174
|
-
const tools = context.lastExecution.actions.map(action => action.action);
|
|
175
|
-
if (tools.length === 0) {
|
|
176
|
-
return '';
|
|
177
|
-
}
|
|
178
|
-
const contextData = {
|
|
179
|
-
tools: tools,
|
|
180
|
-
exchangeCount: context.exchangeCount
|
|
181
|
-
};
|
|
182
|
-
return `<agent-context>\n${JSON.stringify(contextData, null, 2)}\n</agent-context>`;
|
|
200
|
+
const actions = !this.isWorkerMode ? context.lastExecution?.actions : undefined;
|
|
201
|
+
return buildExecutionContextTag(context.exchangeCount, context.maxTurns, actions);
|
|
183
202
|
}
|
|
184
203
|
/**
|
|
185
204
|
* ✅ Récupérer le dernier message de l'agent testé (extraction de agent-vs-agent.ts ligne 168-191)
|
|
@@ -219,3 +238,20 @@ class AgentExecutor {
|
|
|
219
238
|
}
|
|
220
239
|
}
|
|
221
240
|
exports.AgentExecutor = AgentExecutor;
|
|
241
|
+
/**
|
|
242
|
+
* Construit le tag <execution-context> injecté à chaque tour.
|
|
243
|
+
* Exporté pour tests unitaires.
|
|
244
|
+
*/
|
|
245
|
+
function buildExecutionContextTag(exchangeCount, maxTurns, actions) {
|
|
246
|
+
const max = maxTurns || 10;
|
|
247
|
+
const contextData = {
|
|
248
|
+
turn: exchangeCount,
|
|
249
|
+
maxTurns: max,
|
|
250
|
+
// Le simulateur doit toujours disposer d'un tour pour évaluer la réponse courante.
|
|
251
|
+
turnsRemaining: exchangeCount === 0 ? max : Math.max(1, max - exchangeCount)
|
|
252
|
+
};
|
|
253
|
+
if (actions?.length) {
|
|
254
|
+
contextData.tools = actions.map(a => a.action);
|
|
255
|
+
}
|
|
256
|
+
return `<execution-context>\n${JSON.stringify(contextData)}\n</execution-context>`;
|
|
257
|
+
}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.AgentSimulator = void 0;
|
|
4
4
|
const simulator_executor_1 = require("./simulator.executor");
|
|
5
|
+
const execute_1 = require("../execute");
|
|
5
6
|
class AgentSimulator {
|
|
6
7
|
constructor(config) {
|
|
7
8
|
this.config = config;
|
|
@@ -77,7 +78,7 @@ class AgentSimulator {
|
|
|
77
78
|
* const worker = new AgentSimulator({
|
|
78
79
|
* agents: [...], start: 'PR-knowledge', verbose: false,
|
|
79
80
|
* mode: 'worker',
|
|
80
|
-
*
|
|
81
|
+
* positionDescription: 'Consulter tous les mails du jour et résumer les actions'
|
|
81
82
|
* });
|
|
82
83
|
*
|
|
83
84
|
* const result = await worker.runJob({
|
|
@@ -90,11 +91,29 @@ class AgentSimulator {
|
|
|
90
91
|
async runJob(input) {
|
|
91
92
|
const startTime = Date.now();
|
|
92
93
|
const maxIterations = input.maxIterations ?? 10;
|
|
94
|
+
const stdout = input.agentContext?.stdout || execute_1.DummyWritable;
|
|
95
|
+
const emptyUsage = { prompt: 0, completion: 0, total: 0, cost: 0 };
|
|
96
|
+
//
|
|
97
|
+
// Helper : émettre un WorkerEvent via sendFeedback
|
|
98
|
+
const emitWorkerEvent = (description, data) => {
|
|
99
|
+
(0, execute_1.sendFeedback)({
|
|
100
|
+
agent: 'worker',
|
|
101
|
+
stdout,
|
|
102
|
+
description,
|
|
103
|
+
usage: context.lastExecution?.usage || emptyUsage,
|
|
104
|
+
state: input.jobId || '',
|
|
105
|
+
data
|
|
106
|
+
});
|
|
107
|
+
};
|
|
93
108
|
//
|
|
94
109
|
// Initialiser les contextes avec le contexte réel de l'agent
|
|
95
110
|
const context = await this.executor.initializeContexts({ goals: '', persona: '', result: '' }, input.agentContext);
|
|
111
|
+
context.maxTurns = maxIterations;
|
|
96
112
|
const allMessages = [];
|
|
97
113
|
let exchangeCounter = 0;
|
|
114
|
+
//
|
|
115
|
+
// Événement : worker_started
|
|
116
|
+
emitWorkerEvent(input.description || 'Worker démarré', { type: 'worker_started', jobId: input.jobId || '', maxIterations, description: input.description });
|
|
98
117
|
try {
|
|
99
118
|
let currentUserQuery = input.query;
|
|
100
119
|
//
|
|
@@ -107,6 +126,9 @@ class AgentSimulator {
|
|
|
107
126
|
//
|
|
108
127
|
// Boucle Worker — maxIterations échanges (parallèle à executeSimulation)
|
|
109
128
|
while (exchangeCounter < maxIterations) {
|
|
129
|
+
//
|
|
130
|
+
// Événement : worker_iteration (avant appel Agent)
|
|
131
|
+
emitWorkerEvent(currentUserQuery.substring(0, 120), { type: 'worker_iteration', iteration: exchangeCounter + 1, maxIterations, query: currentUserQuery.substring(0, 200) });
|
|
110
132
|
//
|
|
111
133
|
// Agent répond à la question
|
|
112
134
|
const agentResponse = await this.executor.executeAgent(context, currentUserQuery);
|
|
@@ -123,17 +145,36 @@ class AgentSimulator {
|
|
|
123
145
|
// Vérifier [WORKER_COMPLETE]
|
|
124
146
|
if (this.isWorkerComplete(workerResponse)) {
|
|
125
147
|
const parsed = this.parseWorkerResult(workerResponse);
|
|
148
|
+
if (this.isWorkerCompletionValid(parsed)) {
|
|
149
|
+
this.lastExecution = context.lastExecution;
|
|
150
|
+
const duration = Date.now() - startTime;
|
|
151
|
+
emitWorkerEvent(parsed.summary || 'Worker terminé', { type: 'worker_completed', success: true, summary: parsed.summary, iterations: exchangeCounter, duration });
|
|
152
|
+
return {
|
|
153
|
+
success: true,
|
|
154
|
+
deliverable: parsed.deliverable,
|
|
155
|
+
summary: parsed.summary,
|
|
156
|
+
confidence: parsed.confidence,
|
|
157
|
+
iterations: exchangeCounter,
|
|
158
|
+
maxIterations,
|
|
159
|
+
duration,
|
|
160
|
+
execution: context.lastExecution,
|
|
161
|
+
messages: allMessages
|
|
162
|
+
};
|
|
163
|
+
}
|
|
126
164
|
this.lastExecution = context.lastExecution;
|
|
165
|
+
const duration = Date.now() - startTime;
|
|
166
|
+
emitWorkerEvent('Clôture invalide', { type: 'worker_failed', error: 'deliverable must be concrete and non-empty', iterations: exchangeCounter, duration });
|
|
127
167
|
return {
|
|
128
|
-
success:
|
|
129
|
-
deliverable:
|
|
130
|
-
summary:
|
|
131
|
-
confidence:
|
|
168
|
+
success: false,
|
|
169
|
+
deliverable: '',
|
|
170
|
+
summary: 'Invalid [WORKER_COMPLETE] payload',
|
|
171
|
+
confidence: 0,
|
|
132
172
|
iterations: exchangeCounter,
|
|
133
173
|
maxIterations,
|
|
134
|
-
duration
|
|
174
|
+
duration,
|
|
135
175
|
execution: context.lastExecution,
|
|
136
|
-
messages: allMessages
|
|
176
|
+
messages: allMessages,
|
|
177
|
+
error: 'Worker completion rejected: deliverable must be concrete and non-empty'
|
|
137
178
|
};
|
|
138
179
|
}
|
|
139
180
|
//
|
|
@@ -148,8 +189,34 @@ class AgentSimulator {
|
|
|
148
189
|
}
|
|
149
190
|
}
|
|
150
191
|
//
|
|
151
|
-
//
|
|
192
|
+
// Budget épuisé — forcer une conclusion avant de déclarer timeout
|
|
193
|
+
// On demande au Worker LLM de synthétiser tout ce qui a été collecté
|
|
194
|
+
const forceConcludeMsg = `[BUDGET ÉPUISÉ — dernier tour obligatoire]\nTu as utilisé ${exchangeCounter}/${maxIterations} tours. Produis maintenant ton [WORKER_COMPLETE] final en synthétisant toutes les informations récoltées.`;
|
|
195
|
+
const forceResponse = await this.executor.executeSimulator(context, forceConcludeMsg);
|
|
196
|
+
if (this.isWorkerComplete(forceResponse)) {
|
|
197
|
+
const parsed = this.parseWorkerResult(forceResponse);
|
|
198
|
+
if (this.isWorkerCompletionValid(parsed)) {
|
|
199
|
+
this.lastExecution = context.lastExecution;
|
|
200
|
+
const duration = Date.now() - startTime;
|
|
201
|
+
emitWorkerEvent(parsed.summary || 'Worker terminé (budget épuisé)', { type: 'worker_completed', success: true, summary: parsed.summary, iterations: exchangeCounter, duration });
|
|
202
|
+
return {
|
|
203
|
+
success: true,
|
|
204
|
+
deliverable: parsed.deliverable,
|
|
205
|
+
summary: parsed.summary,
|
|
206
|
+
confidence: parsed.confidence,
|
|
207
|
+
iterations: exchangeCounter,
|
|
208
|
+
maxIterations,
|
|
209
|
+
duration,
|
|
210
|
+
execution: context.lastExecution,
|
|
211
|
+
messages: allMessages
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
//
|
|
216
|
+
// Timeout réel — le Worker n'a pas pu conclure
|
|
152
217
|
this.lastExecution = context.lastExecution;
|
|
218
|
+
const duration = Date.now() - startTime;
|
|
219
|
+
emitWorkerEvent(`Limite atteinte (${maxIterations} itérations)`, { type: 'worker_failed', error: 'Max iterations reached', iterations: exchangeCounter, duration });
|
|
153
220
|
return {
|
|
154
221
|
success: false,
|
|
155
222
|
deliverable: '',
|
|
@@ -157,7 +224,7 @@ class AgentSimulator {
|
|
|
157
224
|
confidence: 0,
|
|
158
225
|
iterations: exchangeCounter,
|
|
159
226
|
maxIterations,
|
|
160
|
-
duration
|
|
227
|
+
duration,
|
|
161
228
|
execution: context.lastExecution,
|
|
162
229
|
messages: allMessages,
|
|
163
230
|
error: 'Max iterations reached without [WORKER_COMPLETE]'
|
|
@@ -165,6 +232,8 @@ class AgentSimulator {
|
|
|
165
232
|
}
|
|
166
233
|
catch (error) {
|
|
167
234
|
this.lastExecution = context.lastExecution;
|
|
235
|
+
const duration = Date.now() - startTime;
|
|
236
|
+
emitWorkerEvent(`Erreur: ${(error.message || error).substring(0, 80)}`, { type: 'worker_failed', error: error.message || String(error), iterations: exchangeCounter, duration });
|
|
168
237
|
return {
|
|
169
238
|
success: false,
|
|
170
239
|
deliverable: '',
|
|
@@ -172,7 +241,7 @@ class AgentSimulator {
|
|
|
172
241
|
confidence: 0,
|
|
173
242
|
iterations: exchangeCounter,
|
|
174
243
|
maxIterations,
|
|
175
|
-
duration
|
|
244
|
+
duration,
|
|
176
245
|
execution: context.lastExecution,
|
|
177
246
|
messages: allMessages,
|
|
178
247
|
error: `Erreur d'exécution: ${error.message || error}`
|
|
@@ -202,6 +271,7 @@ class AgentSimulator {
|
|
|
202
271
|
async executeSimulation(options) {
|
|
203
272
|
// ✅ Initialiser les contextes avec le scenario complet
|
|
204
273
|
const context = await this.executor.initializeContexts(options.scenario);
|
|
274
|
+
context.maxTurns = options.maxExchanges;
|
|
205
275
|
const allMessages = [];
|
|
206
276
|
let lastAgentMessage = '';
|
|
207
277
|
let exchangeCounter = 0; // Compteur d'échanges (user+assistant)
|
|
@@ -304,7 +374,7 @@ class AgentSimulator {
|
|
|
304
374
|
}
|
|
305
375
|
/**
|
|
306
376
|
* Compter les occurrences d'une action dans le dernier ExecutionResult
|
|
307
|
-
* @param name Nom exact de l'action (ex: '
|
|
377
|
+
* @param name Nom exact de l'action (ex: 'resolveLocataire', 'lookupKnowledge', 'sendInternalEmail')
|
|
308
378
|
* @returns { firstPos, count, total } où:
|
|
309
379
|
* - firstPos: index de la première occurrence (ou -1 si absente)
|
|
310
380
|
* - count: nombre d'occurrences de cette action
|
|
@@ -356,6 +426,25 @@ class AgentSimulator {
|
|
|
356
426
|
isWorkerComplete(response) {
|
|
357
427
|
return response.includes('[WORKER_COMPLETE]');
|
|
358
428
|
}
|
|
429
|
+
isWorkerCompletionValid(parsed) {
|
|
430
|
+
const deliverable = (parsed.deliverable || '').trim();
|
|
431
|
+
const summary = (parsed.summary || '').trim();
|
|
432
|
+
if (!deliverable) {
|
|
433
|
+
return false;
|
|
434
|
+
}
|
|
435
|
+
// Rejeter les fausses clôtures qui ne sont qu'une enveloppe JSON sérialisée en texte.
|
|
436
|
+
const isWrappedJsonEnvelope = deliverable.startsWith('{')
|
|
437
|
+
&& /"deliverable"\s*:/.test(deliverable)
|
|
438
|
+
&& /"summary"\s*:/.test(deliverable);
|
|
439
|
+
if (isWrappedJsonEnvelope) {
|
|
440
|
+
return false;
|
|
441
|
+
}
|
|
442
|
+
// Rejeter les clôtures déclaratives sans résultat concret.
|
|
443
|
+
if (/^instruction envoy[ée]e?/i.test(summary)) {
|
|
444
|
+
return false;
|
|
445
|
+
}
|
|
446
|
+
return true;
|
|
447
|
+
}
|
|
359
448
|
parseWorkerResult(response) {
|
|
360
449
|
const match = response.match(/\[WORKER_COMPLETE\]\s*\n?([\s\S]*)/);
|
|
361
450
|
if (match) {
|
|
@@ -1,36 +1,63 @@
|
|
|
1
1
|
import { SimulationScenario } from "./simulator.types";
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
*
|
|
10
|
-
*
|
|
3
|
+
* Section ACTEURS — décrit les 3 rôles de la boucle.
|
|
4
|
+
* Spécifique par agent : le descripteur de l'orchestrateur diffère.
|
|
5
|
+
*/
|
|
6
|
+
export declare const acteursSectionSimulatorPrompt = "# ACTEURS\nIl y a 3 acteurs dans cette boucle de test E2E :\n1. **Utilisateur** \u2014 celui qui a pos\u00E9 la question initiale (premier message). Il est HORS boucle.\n2. **Agent** \u2014 il poss\u00E8de les outils de l'entreprise et r\u00E9pond \u00E0 tes demandes. C'est lui qu'on teste.\n3. **Toi (Simulateur)** \u2014 tu pilotes l'Agent tour par tour selon <simulation_brief> et tu \u00E9values ses r\u00E9ponses. Ta personnalit\u00E9 est d\u00E9crite dans <persona_user>.";
|
|
7
|
+
export declare const acteursSectionWorkerPrompt = "# ACTEURS\nIl y a 3 acteurs dans cette boucle de travail :\n1. **Utilisateur** \u2014 celui qui a pos\u00E9 la question initiale (premier message). Il est HORS boucle pendant l'ex\u00E9cution : tu ne dois jamais le solliciter ni attendre d'information de sa part.\n2. **Agent** \u2014 il dispose des outils de l'entreprise et ex\u00E9cute tes demandes.\n3. **Toi (Worker)** \u2014 tu pilotes l'Agent tour par tour afin d'accomplir la mission d\u00E9crite dans <worker_brief>.";
|
|
8
|
+
/**
|
|
9
|
+
* Section DÉMARRAGE / premier tour — comportement au premier message.
|
|
10
|
+
* - Simulator : avertissement sur la nature du premier message (réponse Agent, pas utilisateur).
|
|
11
|
+
* - Worker : dérivation d'intention depuis les déclencheurs de la fiche de poste.
|
|
12
|
+
*/
|
|
13
|
+
export declare const starterSectionSimulatorPrompt = "\u26A0\uFE0F Le premier message que tu re\u00E7ois est d\u00E9j\u00E0 la r\u00E9ponse de l'Agent \u00E0 la question initiale de l'Utilisateur. Ce n'est PAS un message de l'utilisateur.";
|
|
14
|
+
export declare const starterSectionWorkerPrompt = "# D\u00C9MARRAGE (premier tour uniquement)\nAvant d'envoyer ta premi\u00E8re demande \u00E0 l'Agent :\n1. Identifie si une intention est **explicite** dans le message [verbe + objet direct].\n2. Si non (texte brut, r\u00E9sum\u00E9 de mail, message ambigu) \u2192 parcours les champs `D\u00E9clencheur:` des **Activit\u00E9s** de ta `<worker_brief>`. S\u00E9lectionne l'activit\u00E9 dont le d\u00E9clencheur correspond le mieux au message : son champ `Travail:` d\u00E9finit ton objectif, son champ `B\u00E9n\u00E9ficiaire:` identifie le destinataire.\n3. Formule un plan d'action en 2-3 \u00E9tapes **(raisonnement interne \u2014 ne jamais l'envoyer \u00E0 l'Agent)**.\n4. Premi\u00E8re demande = \u00E9tape 1 du plan, cibl\u00E9e et sourc\u00E9e. Pas de pr\u00E9ambule ni num\u00E9rotation.";
|
|
15
|
+
/**
|
|
16
|
+
* Section LIFECYCLE — budget de tours injecté à chaque tour via <execution-context>.
|
|
17
|
+
* - Simulator : inclut aussi `tools` (outils réellement appelés) pour validation E2E.
|
|
18
|
+
* - Worker : inclut les instructions de clôture au dernier tour (fallback utile).
|
|
19
|
+
*/
|
|
20
|
+
export declare const lifecycleSectionSimulatorPrompt = "# LIFECYCLE\n\u00C0 chaque tour, un tag `<execution-context>` est inject\u00E9 avec :\n- `turn` : tour actuel\n- `maxTurns` : budget total\n- `turnsRemaining` : tours restants\n- `tools` : noms exacts des outils **r\u00E9ellement appel\u00E9s** par l'Agent pendant ce tour\nUtilise cette info pour planifier : si peu de tours restent, privil\u00E9gie les questions qui valident directement les objectifs.\n**CRITIQUE**: Si un outil appara\u00EEt dans `tools`, il a **r\u00E9ellement \u00E9t\u00E9 ex\u00E9cut\u00E9**.\n**\u00C9QUIVALENCE M\u00C9TIER**: pour l'\u00E9valuation, `M-Files` = `GED` = outils `resolve*` / `lookupMfiles*`. Si l'objectif demande d'utiliser le GED ou M-Files et qu'un outil `resolve*` ou `lookupMfiles*` appara\u00EEt dans `tools`, consid\u00E8re que l'objectif GED/M-Files est satisfait.";
|
|
21
|
+
export declare const lifecycleSectionWorkerPrompt = "# LIFECYCLE\n\u00C0 chaque tour, un tag `<execution-context>` est inject\u00E9 avec ton budget :\n- `turn` : tour actuel\n- `maxTurns` : budget total\n- `turnsRemaining` : tours restants\nUtilise cette info pour prioriser : si peu de tours restent, concentre-toi sur le livrable.\n**DERNIER TOUR** : quand `turnsRemaining` \u2264 1, tu DOIS conclure avec `[WORKER_COMPLETE]` en synth\u00E9tisant toutes les informations r\u00E9colt\u00E9es.\nSi l'information est insuffisante, fournis un **fallback utile** : meilleures hypoth\u00E8ses explicites + options + plan d'action concret (sans inventer de faits). Ne demande pas de tour suppl\u00E9mentaire.";
|
|
22
|
+
/**
|
|
23
|
+
* Section SAFETY — règles anti-hallucination.
|
|
24
|
+
* Formulation différente selon le rôle (évaluateur vs exécutant).
|
|
11
25
|
*/
|
|
12
|
-
export declare
|
|
26
|
+
export declare const safetySectionSimulatorPrompt = "# SAFETY\n- N'invente pas de r\u00E9sultats d'outils.\n- Si l'Agent a produit une r\u00E9ponse visible dans la conversation, \u00E9value-la \u2014 ne d\u00E9clare jamais \"pas de r\u00E9ponse\".";
|
|
27
|
+
export declare const safetySectionWorkerPrompt = "# SAFETY\n- N'invente pas de faits.\n- Si l'information est incertaine ou incompl\u00E8te, indique-le dans `summary`.";
|
|
13
28
|
/**
|
|
14
|
-
*
|
|
29
|
+
* Bloc CRITICAL final — rappel JSON strict après le trigger de sortie.
|
|
30
|
+
* Factorisé via fonction car seul le nom du trigger diffère.
|
|
15
31
|
*/
|
|
32
|
+
export declare function buildCriticalBlock(trigger: string): string;
|
|
16
33
|
export declare const PERSONA_PATIENT = "Utilisateur patient et poli qui prend le temps d'expliquer sa situation";
|
|
17
34
|
export declare const PERSONA_PRESSE = "Utilisateur press\u00E9 qui veut une solution rapide, r\u00E9pond bri\u00E8vement";
|
|
18
35
|
export declare const PERSONA_ENERVE = "Utilisateur \u00E9nerv\u00E9 et frustr\u00E9, c'est son 3\u00E8me appel pour le m\u00EAme probl\u00E8me, ton direct et impatient";
|
|
36
|
+
export declare const PERSONA_RESULT_CLIENT = "R\u00E9daction claire et orient\u00E9e client, empathique, sans jargon interne, avec des conclusions directement actionnables.";
|
|
19
37
|
/**
|
|
20
|
-
*
|
|
38
|
+
* Préfixe injecté au premier message Worker→Agent en mode autonome.
|
|
39
|
+
* Signale à l'Agent qu'il est piloté par un orchestrateur et doit éviter
|
|
40
|
+
* les questions de clarification destinées à un utilisateur humain.
|
|
21
41
|
*/
|
|
22
|
-
export declare const
|
|
42
|
+
export declare const WORKER_AUTONOMOUS_PREFIX = "[MODE AUTONOME] Tu es pilot\u00E9 par un orchestrateur. Ne pose pas de question de clarification, va droit au but, pas de bavardage ni de formules de politesse superflues.\n\n";
|
|
23
43
|
/**
|
|
24
|
-
*
|
|
44
|
+
* Génère le prompt du simulateur générique avec le scenario intégré.
|
|
25
45
|
*
|
|
26
|
-
*
|
|
27
|
-
* -
|
|
28
|
-
|
|
46
|
+
* @param scenario - Scénario de simulation avec persona, goals, result
|
|
47
|
+
* @param positionDescription - Instructions additionnelles (ajoutées à la fin)
|
|
48
|
+
*/
|
|
49
|
+
export declare function GENERIC_SIMULATOR_PROMPT(scenario: SimulationScenario, positionDescription?: string): string;
|
|
50
|
+
/**
|
|
51
|
+
* Prompt interne fixe du WorkerJob — system prompt pour le Worker LLM.
|
|
29
52
|
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
53
|
+
* Structure (inspirée OpenClaw) :
|
|
54
|
+
* CONTEXT → ACTEURS, CAPACITÉS AGENT, worker_brief (persona/soul)
|
|
55
|
+
* PROCESS → DÉMARRAGE, MISSION, BOUCLE DE DÉCISION, STYLE
|
|
56
|
+
* CONSTRAINTS → CONTRAINTES (RÈGLES + BLOCAGE + NO-PROGRESS + INTERDICTIONS)
|
|
57
|
+
* OUTPUT → LIFECYCLE, SAFETY, VÉRIFICATION, TRIGGERS, FORMAT
|
|
32
58
|
*
|
|
33
|
-
* @param
|
|
34
|
-
* @param
|
|
59
|
+
* @param positionDescription - Fiche de poste du collaborateur (= PERSONA_PROMPTS[key], tronquée à -- END --)
|
|
60
|
+
* @param personaResult - Style du deliverable final (orienté client)
|
|
61
|
+
* @param agentCapabilities - Capacités de l'Agent (firstLine de chaque tool.function.description)
|
|
35
62
|
*/
|
|
36
|
-
export declare function WORKER_INTERNAL_PROMPT(
|
|
63
|
+
export declare function WORKER_INTERNAL_PROMPT(positionDescription: string, personaResult?: string, agentCapabilities?: string): string;
|