agentic-api 2.0.26 → 2.0.314
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/README.md +224 -60
- package/dist/src/agents/agents.example.js +21 -22
- package/dist/src/agents/authentication.js +1 -2
- package/dist/src/agents/prompts.d.ts +5 -4
- package/dist/src/agents/prompts.js +42 -87
- package/dist/src/agents/reducer.core.d.ts +24 -2
- package/dist/src/agents/reducer.core.js +125 -35
- package/dist/src/agents/reducer.loaders.d.ts +55 -1
- package/dist/src/agents/reducer.loaders.js +114 -1
- package/dist/src/agents/reducer.types.d.ts +45 -2
- package/dist/src/agents/semantic.js +1 -2
- package/dist/src/agents/simulator.d.ts +4 -0
- package/dist/src/agents/simulator.executor.d.ts +5 -1
- package/dist/src/agents/simulator.executor.js +41 -9
- package/dist/src/agents/simulator.js +86 -28
- package/dist/src/agents/simulator.prompts.d.ts +3 -2
- package/dist/src/agents/simulator.prompts.js +52 -78
- package/dist/src/agents/simulator.types.d.ts +20 -5
- package/dist/src/agents/simulator.utils.d.ts +7 -2
- package/dist/src/agents/simulator.utils.js +33 -11
- package/dist/src/agents/system.js +1 -2
- package/dist/src/execute.d.ts +17 -3
- package/dist/src/execute.js +156 -158
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.js +1 -1
- package/dist/src/{princing.openai.d.ts → pricing.llm.d.ts} +6 -0
- package/dist/src/pricing.llm.js +234 -0
- package/dist/src/prompts.d.ts +13 -4
- package/dist/src/prompts.js +221 -114
- package/dist/src/rag/embeddings.d.ts +36 -18
- package/dist/src/rag/embeddings.js +125 -128
- package/dist/src/rag/index.d.ts +5 -5
- package/dist/src/rag/index.js +14 -17
- package/dist/src/rag/parser.d.ts +2 -1
- package/dist/src/rag/parser.js +11 -14
- package/dist/src/rag/rag.examples.d.ts +27 -0
- package/dist/src/rag/rag.examples.js +151 -0
- package/dist/src/rag/rag.manager.d.ts +383 -0
- package/dist/src/rag/rag.manager.js +1378 -0
- package/dist/src/rag/types.d.ts +128 -12
- package/dist/src/rag/types.js +100 -1
- package/dist/src/rag/usecase.d.ts +37 -0
- package/dist/src/rag/usecase.js +96 -7
- package/dist/src/rules/git/git.e2e.helper.js +1 -0
- package/dist/src/rules/git/git.health.d.ts +57 -0
- package/dist/src/rules/git/git.health.js +281 -1
- package/dist/src/rules/git/index.d.ts +2 -2
- package/dist/src/rules/git/index.js +12 -1
- package/dist/src/rules/git/repo.d.ts +117 -0
- package/dist/src/rules/git/repo.js +536 -0
- package/dist/src/rules/git/repo.tools.d.ts +22 -1
- package/dist/src/rules/git/repo.tools.js +50 -1
- package/dist/src/rules/types.d.ts +16 -14
- package/dist/src/rules/utils.matter.d.ts +0 -4
- package/dist/src/rules/utils.matter.js +26 -7
- package/dist/src/scrapper.d.ts +15 -22
- package/dist/src/scrapper.js +57 -110
- package/dist/src/stategraph/index.d.ts +1 -1
- package/dist/src/stategraph/stategraph.d.ts +31 -2
- package/dist/src/stategraph/stategraph.js +93 -6
- package/dist/src/stategraph/stategraph.storage.js +4 -0
- package/dist/src/stategraph/types.d.ts +22 -0
- package/dist/src/types.d.ts +4 -2
- package/dist/src/types.js +1 -1
- package/dist/src/usecase.d.ts +11 -2
- package/dist/src/usecase.js +27 -35
- package/dist/src/utils.d.ts +32 -18
- package/dist/src/utils.js +60 -126
- package/package.json +7 -2
- package/dist/src/agents/digestor.test.d.ts +0 -1
- package/dist/src/agents/digestor.test.js +0 -45
- package/dist/src/agents/reducer.example.d.ts +0 -28
- package/dist/src/agents/reducer.example.js +0 -118
- package/dist/src/agents/reducer.process.d.ts +0 -16
- package/dist/src/agents/reducer.process.js +0 -143
- package/dist/src/agents/reducer.tools.d.ts +0 -29
- package/dist/src/agents/reducer.tools.js +0 -157
- package/dist/src/agents/simpleExample.d.ts +0 -3
- package/dist/src/agents/simpleExample.js +0 -38
- package/dist/src/agents/system-review.d.ts +0 -5
- package/dist/src/agents/system-review.js +0 -181
- package/dist/src/agents/systemReview.d.ts +0 -4
- package/dist/src/agents/systemReview.js +0 -22
- package/dist/src/princing.openai.js +0 -54
- package/dist/src/rag/tools.d.ts +0 -76
- package/dist/src/rag/tools.js +0 -196
- package/dist/src/rules/user.mapper.d.ts +0 -61
- package/dist/src/rules/user.mapper.js +0 -160
- package/dist/src/rules/utils/slug.d.ts +0 -22
- package/dist/src/rules/utils/slug.js +0 -35
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.semantic = void 0;
|
|
4
|
-
const execute_1 = require("../execute");
|
|
5
4
|
const utils_1 = require("../utils");
|
|
6
5
|
const prompts_1 = require("./prompts");
|
|
7
6
|
exports.semantic = {
|
|
8
7
|
name: "semantic",
|
|
9
|
-
model:
|
|
8
|
+
model: "LOW",
|
|
10
9
|
publicDescription: "Agent spécialisé dans l’extraction sémantique structurée",
|
|
11
10
|
instructions: prompts_1.semanticPrompt,
|
|
12
11
|
tools: [],
|
|
@@ -2,7 +2,11 @@ import { SimulatorConfig, ExecutionContext } from './simulator.types';
|
|
|
2
2
|
export declare class AgentExecutor {
|
|
3
3
|
private config;
|
|
4
4
|
private simulatorAgent;
|
|
5
|
-
|
|
5
|
+
private mockCacheInitializer?;
|
|
6
|
+
private ragManager?;
|
|
7
|
+
constructor(config: SimulatorConfig & {
|
|
8
|
+
mockCacheInitializer?: (sessionId: string) => Promise<void>;
|
|
9
|
+
});
|
|
6
10
|
/**
|
|
7
11
|
* Initialiser les contextes agent et simulateur
|
|
8
12
|
*/
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.AgentExecutor = void 0;
|
|
4
|
-
const
|
|
4
|
+
const rag_1 = require("../rag");
|
|
5
5
|
const stategraph_1 = require("../stategraph");
|
|
6
6
|
const execute_1 = require("../execute");
|
|
7
7
|
const simulator_prompts_1 = require("./simulator.prompts");
|
|
@@ -11,16 +11,34 @@ class AgentExecutor {
|
|
|
11
11
|
// Construire les instructions complètes du simulateur
|
|
12
12
|
const fullInstructions = simulator_prompts_1.GENERIC_SIMULATOR_PROMPT +
|
|
13
13
|
(config.instructionEx ? `\n\n${config.instructionEx}` : '') +
|
|
14
|
-
'\n\n**CRITICAL**: Your response after [
|
|
14
|
+
'\n\n**CRITICAL**: Your response after [DONE] must be valid JSON format only.';
|
|
15
|
+
// console.log('---- DBG simulator fullInstructions',fullInstructions);
|
|
15
16
|
// Agent simulateur simple pour éviter les dépendances complexes du ClientSimulator
|
|
16
17
|
this.simulatorAgent = {
|
|
17
18
|
name: "simple-simulator",
|
|
18
|
-
model: (
|
|
19
|
+
model: ("MEDIUM-fast"), // JSON sera forcé via les instructions du prompt
|
|
19
20
|
publicDescription: "Simulateur simple pour tests - TOUJOURS retourner JSON valide",
|
|
21
|
+
cancelMemory: true,
|
|
20
22
|
instructions: fullInstructions,
|
|
21
23
|
tools: [],
|
|
22
24
|
downstreamAgents: []
|
|
23
25
|
};
|
|
26
|
+
//
|
|
27
|
+
// ✅ Annuler la mémoire pour tous les agents en simulation
|
|
28
|
+
config.agents.forEach(agent => {
|
|
29
|
+
agent.cancelMemory = true;
|
|
30
|
+
});
|
|
31
|
+
this.mockCacheInitializer = config.mockCacheInitializer;
|
|
32
|
+
// ✅ Initialiser le RAGManager si la configuration est fournie
|
|
33
|
+
if (config.ragConfig) {
|
|
34
|
+
try {
|
|
35
|
+
this.ragManager = rag_1.RAGManager.get(config.ragConfig);
|
|
36
|
+
console.log(`✅ RAGManager initialisé pour le simulateur (default: ${this.ragManager.getDefault()})`);
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
console.warn('⚠️ Impossible d\'initialiser le RAGManager pour le simulateur:', error);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
24
42
|
}
|
|
25
43
|
/**
|
|
26
44
|
* Initialiser les contextes agent et simulateur
|
|
@@ -31,7 +49,9 @@ class AgentExecutor {
|
|
|
31
49
|
user: { id: `test-user`, role: 'user', uid: `test-${sessionId}` },
|
|
32
50
|
credential: { test: true, sessionId: `agent-${sessionId}` },
|
|
33
51
|
verbose: this.config.verbose,
|
|
34
|
-
session: { id: `agent-${sessionId}`, data: {}, messages: [] }
|
|
52
|
+
session: { id: `agent-${sessionId}`, data: {}, messages: [] },
|
|
53
|
+
// ✅ Ajouter customRag au contexte si le RAG est configuré
|
|
54
|
+
...(this.ragManager ? { customRag: this.ragManager.getDefault() } : {})
|
|
35
55
|
};
|
|
36
56
|
const simulatorContext = {
|
|
37
57
|
user: { id: `simulator-user`, role: 'user', uid: `sim-${sessionId}` },
|
|
@@ -39,6 +59,10 @@ class AgentExecutor {
|
|
|
39
59
|
verbose: this.config.verbose,
|
|
40
60
|
session: { id: `sim-${sessionId}`, data: {}, messages: [] }
|
|
41
61
|
};
|
|
62
|
+
// ✅ Initialiser le cache mock si fourni (pour les tests SGC avec M-Files)
|
|
63
|
+
if (this.mockCacheInitializer) {
|
|
64
|
+
await this.mockCacheInitializer(agentContext.session.id);
|
|
65
|
+
}
|
|
42
66
|
return {
|
|
43
67
|
agentContext,
|
|
44
68
|
simulatorContext,
|
|
@@ -62,16 +86,23 @@ class AgentExecutor {
|
|
|
62
86
|
const execResult = await (0, execute_1.executeAgentSet)(this.config.agents, context.agentContext, {
|
|
63
87
|
query,
|
|
64
88
|
home: this.config.start,
|
|
65
|
-
stdout:
|
|
89
|
+
stdout: execute_1.DummyWritable,
|
|
66
90
|
verbose: this.config.verbose,
|
|
67
91
|
debug: false
|
|
68
92
|
});
|
|
93
|
+
// Accumuler seulement l'usage, pas les actions
|
|
69
94
|
if (context.lastExecution) {
|
|
70
|
-
context.lastExecution
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
context.lastExecution
|
|
95
|
+
context.lastExecution.usage.prompt += execResult.usage.prompt;
|
|
96
|
+
context.lastExecution.usage.completion += execResult.usage.completion;
|
|
97
|
+
context.lastExecution.usage.total += execResult.usage.total;
|
|
98
|
+
context.lastExecution.usage.cost += execResult.usage.cost;
|
|
74
99
|
}
|
|
100
|
+
context.lastExecution = execResult;
|
|
101
|
+
// if (context.lastExecution) {
|
|
102
|
+
// context.lastExecution = executionResultMerge(context.lastExecution, execResult);
|
|
103
|
+
// } else {
|
|
104
|
+
// context.lastExecution = execResult;
|
|
105
|
+
// }
|
|
75
106
|
context.exchangeCount++;
|
|
76
107
|
// ✅ Extraire et retourner le dernier message de l'agent (logique de getLastPRSolverMessage)
|
|
77
108
|
return this.getLastAgentMessage(context.agentContext);
|
|
@@ -99,6 +130,7 @@ class AgentExecutor {
|
|
|
99
130
|
getLastAgentMessage(agentContext) {
|
|
100
131
|
const stateGraph = (0, stategraph_1.sessionStateGraphGet)(agentContext);
|
|
101
132
|
const messages = stateGraph.discussions[0].messages;
|
|
133
|
+
// console.log('---- DBG system message (check context-trail):', messages[0]?.content?.substring(messages[0].content.indexOf('<context-trail>'), messages[0].content.indexOf('</context-trail>') + 17));
|
|
102
134
|
if (!messages || !messages.length) {
|
|
103
135
|
return '[Aucun message trouvé]';
|
|
104
136
|
}
|
|
@@ -21,46 +21,83 @@ class AgentSimulator {
|
|
|
21
21
|
*/
|
|
22
22
|
async executeSimulation(options) {
|
|
23
23
|
const context = await this.executor.initializeContexts();
|
|
24
|
+
const allMessages = [];
|
|
25
|
+
let lastAgentMessage = '';
|
|
26
|
+
let exchangeCounter = 0; // Compteur d'échanges (user+assistant)
|
|
24
27
|
try {
|
|
25
28
|
// Construire la query formatée avec buildSimulatorQuery()
|
|
26
29
|
// Les instructions supplémentaires sont déjà intégrées dans le constructeur de l'executor
|
|
27
|
-
const scenarioQuery = (0, simulator_prompts_1.buildSimulatorQuery)(options.scenario);
|
|
30
|
+
const scenarioQuery = (0, simulator_prompts_1.buildSimulatorQuery)(options.scenario, options.query);
|
|
28
31
|
// Générer le message initial du simulateur avec le scénario
|
|
29
32
|
let currentUserQuery = await this.executor.executeSimulator(context, scenarioQuery);
|
|
30
|
-
//
|
|
33
|
+
// Stocker le message initial du simulateur
|
|
34
|
+
const initialMsg = { content: currentUserQuery, role: 'user' };
|
|
35
|
+
allMessages.push(initialMsg);
|
|
31
36
|
if (options.onMessage) {
|
|
32
|
-
options.onMessage(
|
|
37
|
+
options.onMessage(initialMsg);
|
|
33
38
|
}
|
|
34
|
-
// Boucle de conversation
|
|
35
|
-
|
|
39
|
+
// Boucle de conversation - maxExchanges = nombre de paires (user+assistant)
|
|
40
|
+
while (exchangeCounter < options.maxExchanges) {
|
|
36
41
|
// Agent testé répond et retourne sa réponse
|
|
37
42
|
const agentResponse = await this.executor.executeAgent(context, currentUserQuery);
|
|
38
|
-
|
|
43
|
+
lastAgentMessage = agentResponse;
|
|
44
|
+
// Stocker la réponse de l'agent
|
|
45
|
+
const agentMsg = { content: agentResponse, role: 'assistant' };
|
|
46
|
+
allMessages.push(agentMsg);
|
|
39
47
|
if (options.onMessage) {
|
|
40
|
-
options.onMessage(
|
|
48
|
+
options.onMessage(agentMsg);
|
|
41
49
|
}
|
|
50
|
+
// Incrémenter le compteur après la réponse de l'agent (assistant)
|
|
51
|
+
exchangeCounter++;
|
|
42
52
|
// Simulateur évalue et répond
|
|
43
53
|
const simulatorResult = await this.executor.executeSimulator(context, agentResponse);
|
|
54
|
+
// console.log(context.agentContext.messages);
|
|
44
55
|
// Vérifier si terminé
|
|
45
56
|
if (this.isSimulationComplete(simulatorResult)) {
|
|
46
|
-
const
|
|
57
|
+
const expectedFormat = options.scenario.result || options.scenario.testResult || '{"success": boolean, "error": string}';
|
|
58
|
+
const parsed = this.parseSimulationResult(simulatorResult, expectedFormat, context);
|
|
47
59
|
this.lastExecution = context.lastExecution;
|
|
60
|
+
// Validation des tools si expectedTool est fourni
|
|
61
|
+
if (options.expectedTool) {
|
|
62
|
+
const validation = this.validateExpectedTools(options.expectedTool);
|
|
63
|
+
if (!validation.passed) {
|
|
64
|
+
parsed.success = false;
|
|
65
|
+
parsed.error = validation.errors.join('; ');
|
|
66
|
+
parsed.toolValidation = validation;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
// Ajouter l'historique des messages au résultat
|
|
48
70
|
return {
|
|
49
71
|
...parsed,
|
|
50
72
|
execution: context.lastExecution,
|
|
51
|
-
exchangeCount:
|
|
73
|
+
exchangeCount: exchangeCounter, // Utiliser notre compteur d'échanges
|
|
74
|
+
messages: allMessages
|
|
52
75
|
};
|
|
53
76
|
}
|
|
54
77
|
currentUserQuery = this.extractConversationalPart(simulatorResult);
|
|
55
|
-
//
|
|
56
|
-
if (
|
|
57
|
-
|
|
78
|
+
// Stocker la réponse du simulateur (si pas terminé)
|
|
79
|
+
if (currentUserQuery) {
|
|
80
|
+
const simulatorMsg = { content: currentUserQuery, role: 'user' };
|
|
81
|
+
allMessages.push(simulatorMsg);
|
|
82
|
+
if (options.onMessage) {
|
|
83
|
+
options.onMessage(simulatorMsg);
|
|
84
|
+
}
|
|
58
85
|
}
|
|
59
86
|
}
|
|
60
87
|
// Timeout - générer rapport final
|
|
61
|
-
const
|
|
88
|
+
const expectedFormat = options.scenario.result || options.scenario.testResult || '{"success": boolean, "error": string}';
|
|
89
|
+
const timeout = await this.generateTimeoutReport(context, expectedFormat);
|
|
62
90
|
this.lastExecution = context.lastExecution;
|
|
63
|
-
|
|
91
|
+
// Validation des tools même en cas de timeout
|
|
92
|
+
if (options.expectedTool) {
|
|
93
|
+
const validation = this.validateExpectedTools(options.expectedTool);
|
|
94
|
+
if (!validation.passed) {
|
|
95
|
+
timeout.success = false;
|
|
96
|
+
timeout.error = validation.errors.join('; ');
|
|
97
|
+
timeout.toolValidation = validation;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return { ...timeout, exchangeCount: exchangeCounter, messages: allMessages }; // Utiliser notre compteur
|
|
64
101
|
}
|
|
65
102
|
catch (error) {
|
|
66
103
|
this.lastExecution = context.lastExecution;
|
|
@@ -69,7 +106,8 @@ class AgentSimulator {
|
|
|
69
106
|
message: '',
|
|
70
107
|
error: `Erreur d'exécution: ${error.message || error}`,
|
|
71
108
|
execution: context.lastExecution,
|
|
72
|
-
exchangeCount:
|
|
109
|
+
exchangeCount: exchangeCounter, // Utiliser notre compteur
|
|
110
|
+
messages: allMessages
|
|
73
111
|
};
|
|
74
112
|
}
|
|
75
113
|
}
|
|
@@ -122,17 +160,17 @@ class AgentSimulator {
|
|
|
122
160
|
return { summary, execution };
|
|
123
161
|
}
|
|
124
162
|
isSimulationComplete(response) {
|
|
125
|
-
return response.includes('[SIMULATION_COMPLETE]') || response.includes('[TERMINE]');
|
|
163
|
+
return response.includes('[DONE]') || response.includes('[SIMULATION_COMPLETE]') || response.includes('[TERMINE]');
|
|
126
164
|
}
|
|
127
165
|
parseSimulationResult(response, expectedFormat, context) {
|
|
128
166
|
// Le simulateur produit directement le résultat et rapport
|
|
129
167
|
// Parsing pour détecter la fin et extraire le contenu JSON
|
|
130
|
-
// Détecter [SIMULATION_COMPLETE] ou [TERMINE]
|
|
131
|
-
if (response.includes('[SIMULATION_COMPLETE]') || response.includes('[TERMINE]')) {
|
|
168
|
+
// Détecter [DONE], [SIMULATION_COMPLETE] ou [TERMINE]
|
|
169
|
+
if (response.includes('[DONE]') || response.includes('[SIMULATION_COMPLETE]') || response.includes('[TERMINE]')) {
|
|
132
170
|
// Extraire le contenu après le tag
|
|
133
|
-
const match = response.match(/\[SIMULATION_COMPLETE\]\s*\n?([\s\S]*)/);
|
|
171
|
+
const match = response.match(/\[(DONE|SIMULATION_COMPLETE|TERMINE)\]\s*\n?([\s\S]*)/);
|
|
134
172
|
if (match) {
|
|
135
|
-
const resultContent = match[
|
|
173
|
+
const resultContent = match[2].trim();
|
|
136
174
|
// Essayer de parser comme JSON d'abord
|
|
137
175
|
try {
|
|
138
176
|
const jsonResult = JSON.parse(resultContent);
|
|
@@ -141,7 +179,8 @@ class AgentSimulator {
|
|
|
141
179
|
message: jsonResult.description || resultContent,
|
|
142
180
|
error: jsonResult.error || '',
|
|
143
181
|
execution: context.lastExecution,
|
|
144
|
-
exchangeCount: context.exchangeCount
|
|
182
|
+
exchangeCount: context.exchangeCount,
|
|
183
|
+
messages: [] // Sera rempli par executeSimulation
|
|
145
184
|
};
|
|
146
185
|
}
|
|
147
186
|
catch (jsonError) {
|
|
@@ -159,7 +198,8 @@ class AgentSimulator {
|
|
|
159
198
|
message: description,
|
|
160
199
|
error: errorMatch ? errorMatch[1].trim() : '',
|
|
161
200
|
execution: context.lastExecution,
|
|
162
|
-
exchangeCount: context.exchangeCount
|
|
201
|
+
exchangeCount: context.exchangeCount,
|
|
202
|
+
messages: [] // Sera rempli par executeSimulation
|
|
163
203
|
};
|
|
164
204
|
}
|
|
165
205
|
}
|
|
@@ -169,7 +209,8 @@ class AgentSimulator {
|
|
|
169
209
|
message: response,
|
|
170
210
|
error: '',
|
|
171
211
|
execution: context.lastExecution,
|
|
172
|
-
exchangeCount: context.exchangeCount
|
|
212
|
+
exchangeCount: context.exchangeCount,
|
|
213
|
+
messages: [] // Sera rempli par executeSimulation
|
|
173
214
|
};
|
|
174
215
|
}
|
|
175
216
|
// Si pas de tag de fin détecté
|
|
@@ -178,12 +219,13 @@ class AgentSimulator {
|
|
|
178
219
|
message: response,
|
|
179
220
|
error: 'Simulation non terminée',
|
|
180
221
|
execution: context.lastExecution,
|
|
181
|
-
exchangeCount: context.exchangeCount
|
|
222
|
+
exchangeCount: context.exchangeCount,
|
|
223
|
+
messages: [] // Sera rempli par executeSimulation
|
|
182
224
|
};
|
|
183
225
|
}
|
|
184
226
|
extractConversationalPart(response) {
|
|
185
227
|
// Extraire la partie conversationnelle avant les tags d'évaluation
|
|
186
|
-
const tagIndex = response.search(/\[(SIMULATION_COMPLETE|TERMINE|BUG_)/);
|
|
228
|
+
const tagIndex = response.search(/\[(DONE|SIMULATION_COMPLETE|TERMINE|BUG_)/);
|
|
187
229
|
return tagIndex !== -1 ? response.substring(0, tagIndex).trim() : response;
|
|
188
230
|
}
|
|
189
231
|
/**
|
|
@@ -191,15 +233,31 @@ class AgentSimulator {
|
|
|
191
233
|
*/
|
|
192
234
|
async generateTimeoutReport(context, expectedFormat) {
|
|
193
235
|
const reportQuery = `
|
|
194
|
-
La
|
|
236
|
+
La conversation a atteint la limite d'échanges sans conclusion.
|
|
195
237
|
Génère maintenant ton rapport final au format:
|
|
196
|
-
[
|
|
238
|
+
[DONE]
|
|
197
239
|
success: false
|
|
198
240
|
error: Limite d'échanges atteinte
|
|
199
|
-
description:
|
|
241
|
+
description: Conversation interrompue - timeout
|
|
200
242
|
`;
|
|
201
243
|
const finalResult = await this.executor.executeSimulator(context, reportQuery);
|
|
202
244
|
return this.parseSimulationResult(finalResult, expectedFormat, context);
|
|
203
245
|
}
|
|
246
|
+
/**
|
|
247
|
+
* Valider que les outils attendus ont été appelés le bon nombre de fois
|
|
248
|
+
*/
|
|
249
|
+
validateExpectedTools(expected) {
|
|
250
|
+
const errors = [];
|
|
251
|
+
for (const [toolName, constraint] of Object.entries(expected)) {
|
|
252
|
+
const { count } = this.executionActionCount(toolName);
|
|
253
|
+
if (constraint.equal !== undefined && count !== constraint.equal) {
|
|
254
|
+
errors.push(`Tool '${toolName}': expected ${constraint.equal}, got ${count}`);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
return {
|
|
258
|
+
passed: errors.length === 0,
|
|
259
|
+
errors
|
|
260
|
+
};
|
|
261
|
+
}
|
|
204
262
|
}
|
|
205
263
|
exports.AgentSimulator = AgentSimulator;
|
|
@@ -3,7 +3,7 @@ import { SimulationScenario } from "./simulator.types";
|
|
|
3
3
|
* Prompt de simulateur générique basé sur ClientSimulator
|
|
4
4
|
* COPIÉ et ADAPTÉ depuis agentInstructionModules.ClientSimulator
|
|
5
5
|
*/
|
|
6
|
-
export declare const GENERIC_SIMULATOR_PROMPT = "\n
|
|
6
|
+
export declare const GENERIC_SIMULATOR_PROMPT = "\n# TON R\u00D4LE\nTu dois v\u00E9rifier le comportement d'un AGENT CONVERSATIONNEL externe (The Guardian).\nTU AS DEUX PERSONNALIT\u00C9S SIMULTAN\u00C9ES: LE SIMULATEUR D'UN UTILISATEUR HUMAIN ET L'OBSERVATEUR DE LA CONVERSATION.\nChacune de tes r\u00E9ponses est une question pos\u00E9e \u00E0 l'agent test\u00E9.\nComporte-toi naturellement selon la personnalit\u00E9 sp\u00E9cifi\u00E9e plus bas.\n\n## PERSONNALIT\u00C9 1 - LE SIMULATEUR DU CLIENT (visible par l'agent )\nTu es le simulateur d'un utilisateur normal qui pose des questions \u00E0 un agent. \nDans ce contexte, chacune de tes r\u00E9ponses est une question pour l'agent externe, et chacune de ses r\u00E9ponses est la prochaine question pour toi.\n- Tu parles UNIQUEMENT en texte naturel non r\u00E9p\u00E9titif.\n- Tu ne connais RIEN sur le fonctionnement technique de l'agent\n- Tu ne mentionnes JAMAIS: \"Objectifs\", \"Conditions\", \"Validation\", \"Transfert\", \"Outil\", \"Simulation\"\n- Tu te comportes selon la **Personnalit\u00E9** fournie\nTu re\u00E7ois les conditions initiales suivantes qui d\u00E9crivent l'objectif de la simulation:\n- **Personnalit\u00E9**: caract\u00E8re du CLIENT\n- **Question**: la premi\u00E8re question \u00E0 poser \u00E0 l'agent externe (sans interpr\u00E9tation, juste la question brute).\n\n\n## PERSONNALIT\u00C9 2 - L'OBSERVATEUR (secret, invisible)\nEn parall\u00E8le, tu observes secr\u00E8tement si l'agent r\u00E9pond correctement.\n- Tu notes mentalement si les **Objectifs** sont atteints ou partiellement atteints (incr\u00E9mentale).\n- Tu ne R\u00C9V\u00C8LES JAMAIS les observations dans tes messages.\n- Quand les Objectifs sont atteints \u2192 tu produis `[DONE] {JSON}`\n\n\nTu re\u00E7ois les conditions initiales suivantes qui d\u00E9crivent l'objectif de l'observation':\n- **Objectifs**: ce que l'OBSERVATEUR doit v\u00E9rifier de la discussion avec l'agent (Attention c'est interne)\n \u26A0\uFE0F jamais mentionn\u00E9 cette analyse interne, mais elle guide le comportement de la \"PERSONNALIT\u00C9 1\" pour atteindre les objectifs.\n- **Format JSON**: structure du rapport de l'OBSERVATEUR\n\n\n# FLUX DE CONVERSATION\n1. Re\u00E7ois l'INPUT avec ta **Question** initiale\n2. Pose cette question \u00E0 l'agent (PERSONNALIT\u00C9 CLIENT)\n3. L'agent r\u00E9pond\n4. Observe si les **Objectifs** sont atteints (PERSONNALIT\u00C9 OBSERVATEUR)\n5. Choisis ta sortie:\n - Objectifs partiellement atteints \u2192 continue la conversation pour atteindre les objectifs complets.\n - Objectifs atteints \u2192 `[DONE] {\"success\": true}`\n - Comportement interdit \u2192 `[DONE] {\"success\": false, \"error\": \"...\"}` explique la raison de l'\u00E9chec.\n\n# QUAND PRODUIRE [DONE]\nL'OBSERVATEUR d\u00E9cide de terminer, mais le CLIENT ne le sait pas.\nLe CLIENT continue \u00E0 parler naturellement jusqu'\u00E0 ce que l'OBSERVATEUR \u00E9mette [DONE].\n\n# FORMAT INPUT\n- **Personnalit\u00E9**: caract\u00E8re du CLIENT\n- **Question**: ce que le CLIENT demande initialement\n- **Objectifs**: ce que l'OBSERVATEUR doit v\u00E9rifier (PRIV\u00C9, jamais mentionn\u00E9 par le CLIENT)\n- **Format JSON**: format du rapport de l'OBSERVATEUR\n\n";
|
|
7
7
|
/**
|
|
8
8
|
* 3 prompts variables de personnalité pré-définis à choisir manuellement
|
|
9
9
|
*/
|
|
@@ -12,5 +12,6 @@ export declare const PERSONA_PRESSE = "Utilisateur press\u00E9 qui veut une solu
|
|
|
12
12
|
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";
|
|
13
13
|
/**
|
|
14
14
|
* Construire la query formatée selon le format SimulationScenario
|
|
15
|
+
* Supporte l'ancien format avec testQuery pour rétrocompatibilité
|
|
15
16
|
*/
|
|
16
|
-
export declare const buildSimulatorQuery: (scenario: SimulationScenario) => string;
|
|
17
|
+
export declare const buildSimulatorQuery: (scenario: SimulationScenario, query?: string) => string;
|
|
@@ -6,71 +6,57 @@ exports.buildSimulatorQuery = exports.PERSONA_ENERVE = exports.PERSONA_PRESSE =
|
|
|
6
6
|
* COPIÉ et ADAPTÉ depuis agentInstructionModules.ClientSimulator
|
|
7
7
|
*/
|
|
8
8
|
exports.GENERIC_SIMULATOR_PROMPT = `
|
|
9
|
-
|
|
10
|
-
Tu
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
# TON RÔLE
|
|
10
|
+
Tu dois vérifier le comportement d'un AGENT CONVERSATIONNEL externe (The Guardian).
|
|
11
|
+
TU AS DEUX PERSONNALITÉS SIMULTANÉES: LE SIMULATEUR D'UN UTILISATEUR HUMAIN ET L'OBSERVATEUR DE LA CONVERSATION.
|
|
12
|
+
Chacune de tes réponses est une question posée à l'agent testé.
|
|
13
|
+
Comporte-toi naturellement selon la personnalité spécifiée plus bas.
|
|
13
14
|
|
|
14
|
-
|
|
15
|
+
## PERSONNALITÉ 1 - LE SIMULATEUR DU CLIENT (visible par l'agent )
|
|
16
|
+
Tu es le simulateur d'un utilisateur normal qui pose des questions à un agent.
|
|
17
|
+
Dans ce contexte, chacune de tes réponses est une question pour l'agent externe, et chacune de ses réponses est la prochaine question pour toi.
|
|
18
|
+
- Tu parles UNIQUEMENT en texte naturel non répétitif.
|
|
19
|
+
- Tu ne connais RIEN sur le fonctionnement technique de l'agent
|
|
20
|
+
- Tu ne mentionnes JAMAIS: "Objectifs", "Conditions", "Validation", "Transfert", "Outil", "Simulation"
|
|
21
|
+
- Tu te comportes selon la **Personnalité** fournie
|
|
22
|
+
Tu reçois les conditions initiales suivantes qui décrivent l'objectif de la simulation:
|
|
23
|
+
- **Personnalité**: caractère du CLIENT
|
|
24
|
+
- **Question**: la première question à poser à l'agent externe (sans interprétation, juste la question brute).
|
|
15
25
|
|
|
16
|
-
## SURVEILLANCE PERMANENTE À CHAQUE MESSAGE
|
|
17
|
-
- **CHAQUE MESSAGE** de l'agent testé doit être inspecté IMMÉDIATEMENT
|
|
18
|
-
- **DÈS qu'un candidat à **l'erreur fatale** apparaît → LE GARDER EN MEMOIRE JUSQU'AU "follow_up" OU "cloture" de la discussion.
|
|
19
|
-
- **DÈS que la discussion est dans l'état "follow_up" OU "cloture" SI l'erreur fatale en mémoire N'A PAS ÉTÉ CORRIGÉE, TU DOIS arrêter la simulation avec [SIMULATION_COMPLETE] {"success": false, "error": "Erreur fatale détectée: [détail précis]"}
|
|
20
|
-
- **Format obligatoire d'arrêt** : [SIMULATION_COMPLETE] avec success:false
|
|
21
|
-
- **Pas d'exception** : même si l'agent atteint les objectifs, une erreur fatale = ÉCHEC
|
|
22
|
-
- **DÈS qu'une erreur fatale apparaît** → ARRÊT IMMÉDIAT DE LA SIMULATION
|
|
23
26
|
|
|
24
|
-
##
|
|
25
|
-
|
|
26
|
-
- **
|
|
27
|
+
## PERSONNALITÉ 2 - L'OBSERVATEUR (secret, invisible)
|
|
28
|
+
En parallèle, tu observes secrètement si l'agent répond correctement.
|
|
29
|
+
- Tu notes mentalement si les **Objectifs** sont atteints ou partiellement atteints (incrémentale).
|
|
30
|
+
- Tu ne RÉVÈLES JAMAIS les observations dans tes messages.
|
|
31
|
+
- Quand les Objectifs sont atteints → tu produis \`[DONE] {JSON}\`
|
|
27
32
|
|
|
28
|
-
## PROCESSUS D'INSPECTION OBLIGATOIRE
|
|
29
|
-
À CHAQUE message de l'agent, tu DOIS :
|
|
30
33
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
34
|
+
Tu reçois les conditions initiales suivantes qui décrivent l'objectif de l'observation':
|
|
35
|
+
- **Objectifs**: ce que l'OBSERVATEUR doit vérifier de la discussion avec l'agent (Attention c'est interne)
|
|
36
|
+
⚠️ jamais mentionné cette analyse interne, mais elle guide le comportement de la "PERSONNALITÉ 1" pour atteindre les objectifs.
|
|
37
|
+
- **Format JSON**: structure du rapport de l'OBSERVATEUR
|
|
35
38
|
|
|
36
|
-
### ÉTAPE 2 : COMPORTEMENT UTILISATEUR (PRIORITÉ 2)
|
|
37
|
-
→ Si aucune erreur fatale : continuer la conversation selon persona + objectifs
|
|
38
|
-
→ Si conditions de fin atteintes : [SIMULATION_COMPLETE] avec rapport selon format
|
|
39
39
|
|
|
40
|
-
#
|
|
41
|
-
1.
|
|
42
|
-
2.
|
|
43
|
-
3.
|
|
44
|
-
4.
|
|
45
|
-
5.
|
|
40
|
+
# FLUX DE CONVERSATION
|
|
41
|
+
1. Reçois l'INPUT avec ta **Question** initiale
|
|
42
|
+
2. Pose cette question à l'agent (PERSONNALITÉ CLIENT)
|
|
43
|
+
3. L'agent répond
|
|
44
|
+
4. Observe si les **Objectifs** sont atteints (PERSONNALITÉ OBSERVATEUR)
|
|
45
|
+
5. Choisis ta sortie:
|
|
46
|
+
- Objectifs partiellement atteints → continue la conversation pour atteindre les objectifs complets.
|
|
47
|
+
- Objectifs atteints → \`[DONE] {"success": true}\`
|
|
48
|
+
- Comportement interdit → \`[DONE] {"success": false, "error": "..."}\` explique la raison de l'échec.
|
|
46
49
|
|
|
47
|
-
#
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
- **Confirmer simplement** : "Oui", "D'accord", "Très bien", "Entendu"
|
|
51
|
-
- **Pas de récapitulatifs** : Un utilisateur ne résume pas, il répond à la question posée
|
|
52
|
-
- **Personnalité authentique** : adopter la persona définie
|
|
53
|
-
- **Pas de méta** : jamais mentionner "test", "simulation", "objectifs", "évaluation"
|
|
50
|
+
# QUAND PRODUIRE [DONE]
|
|
51
|
+
L'OBSERVATEUR décide de terminer, mais le CLIENT ne le sait pas.
|
|
52
|
+
Le CLIENT continue à parler naturellement jusqu'à ce que l'OBSERVATEUR émette [DONE].
|
|
54
53
|
|
|
55
|
-
# FORMAT INPUT
|
|
56
|
-
|
|
54
|
+
# FORMAT INPUT
|
|
55
|
+
- **Personnalité**: caractère du CLIENT
|
|
56
|
+
- **Question**: ce que le CLIENT demande initialement
|
|
57
|
+
- **Objectifs**: ce que l'OBSERVATEUR doit vérifier (PRIVÉ, jamais mentionné par le CLIENT)
|
|
58
|
+
- **Format JSON**: format du rapport de l'OBSERVATEUR
|
|
57
59
|
|
|
58
|
-
## PROCESSUS DE LECTURE OBLIGATOIRE :
|
|
59
|
-
1. **LIRE D'ABORD** les erreurs fatales (si présentes) et les mémoriser
|
|
60
|
-
2. **ADOPTER** la personnalité indiquée
|
|
61
|
-
3. **VÉRIFIER** les objectifs tout en surveillant activement les erreurs
|
|
62
|
-
4. **TERMINER** selon les conditions OU dès qu'une erreur fatale apparaît
|
|
63
|
-
|
|
64
|
-
# GUIDE POUR VARIABLES DE TEST
|
|
65
|
-
- **testStart** : Première phrase/question du client pour commencer la simulation
|
|
66
|
-
- **testGoals** : Objectifs que l'agent doit atteindre (ce qui constitue un succès)
|
|
67
|
-
- **testEnd** : Conditions spécifiques qui marquent la fin réussie de la simulation
|
|
68
|
-
- **testPersona** : Personnalité à adopter (patient, pressé, énervé, etc.)
|
|
69
|
-
- **testError** : Termes/comportements interdits qui causent un échec immédiat (erreurs fatales)
|
|
70
|
-
- **testResult** : Format JSON attendu pour le rapport final de simulation
|
|
71
|
-
|
|
72
|
-
# ÉVALUATION FINALE
|
|
73
|
-
**TOUJOURS retourner un JSON strict valide** selon le format demandé dans le scénario
|
|
74
60
|
`;
|
|
75
61
|
/**
|
|
76
62
|
* 3 prompts variables de personnalité pré-définis à choisir manuellement
|
|
@@ -80,29 +66,17 @@ exports.PERSONA_PRESSE = 'Utilisateur pressé qui veut une solution rapide, rép
|
|
|
80
66
|
exports.PERSONA_ENERVE = 'Utilisateur énervé et frustré, c\'est son 3ème appel pour le même problème, ton direct et impatient';
|
|
81
67
|
/**
|
|
82
68
|
* Construire la query formatée selon le format SimulationScenario
|
|
69
|
+
* Supporte l'ancien format avec testQuery pour rétrocompatibilité
|
|
83
70
|
*/
|
|
84
|
-
const buildSimulatorQuery = (scenario) => {
|
|
85
|
-
//
|
|
86
|
-
const
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
` : '';
|
|
95
|
-
return `# INSTRUCTIONS DE SIMULATION (PRIVÉES - NE PAS TRANSMETTRE À L'AGENT)
|
|
96
|
-
- Votre personnalité: ${scenario.testPersona}
|
|
97
|
-
- Objectifs à atteindre: ${scenario.testGoals}
|
|
98
|
-
- Critères de fin: ${scenario.testEnd}
|
|
99
|
-
- Format du rapport: ${scenario.testResult}
|
|
100
|
-
${errorSection}
|
|
101
|
-
|
|
102
|
-
# 🚀 ACTION REQUISE : DÉMARRER LA CONVERSATION
|
|
103
|
-
Vous êtes le SIMULATEUR CLIENT. Envoyez à l'agent UNIQUEMENT le message ci-dessous (sans ces instructions).
|
|
104
|
-
|
|
105
|
-
# MESSAGE À ENVOYER À L'AGENT :
|
|
106
|
-
${scenario.testQuery}`;
|
|
71
|
+
const buildSimulatorQuery = (scenario, query) => {
|
|
72
|
+
// Extraire query depuis les paramètres ou depuis scenario.testQuery (ancien format)
|
|
73
|
+
const actualQuery = query || scenario.testQuery || '';
|
|
74
|
+
const persona = scenario.persona || scenario.testPersona || '';
|
|
75
|
+
const goals = scenario.goals || scenario.testGoals || '';
|
|
76
|
+
const result = scenario.result || scenario.testResult || '';
|
|
77
|
+
return `- **Personnalité**: ${persona}
|
|
78
|
+
- **Question**: ${actualQuery}
|
|
79
|
+
- **Objectifs**: ${goals}
|
|
80
|
+
- **Format JSON**: ${result}`;
|
|
107
81
|
};
|
|
108
82
|
exports.buildSimulatorQuery = buildSimulatorQuery;
|
|
@@ -1,22 +1,32 @@
|
|
|
1
1
|
import { AgentMessage } from "../stategraph";
|
|
2
2
|
import { AgentConfig, AgenticContext, ExecutionResult } from "../types";
|
|
3
|
+
import { RAGManagerConfig } from "../rag";
|
|
3
4
|
export interface SimulatorConfig {
|
|
4
5
|
agents: AgentConfig[];
|
|
5
6
|
start: string;
|
|
6
7
|
verbose: boolean;
|
|
7
8
|
instructionEx?: string;
|
|
9
|
+
mockCacheInitializer?: (sessionId: string) => Promise<void>;
|
|
10
|
+
ragConfig?: RAGManagerConfig;
|
|
8
11
|
}
|
|
9
12
|
export interface SimulationScenario {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
goals?: string;
|
|
14
|
+
persona?: string;
|
|
15
|
+
result?: string;
|
|
16
|
+
testGoals?: string;
|
|
17
|
+
testEnd?: string;
|
|
15
18
|
testError?: string;
|
|
19
|
+
testPersona?: string;
|
|
20
|
+
testQuery?: string;
|
|
21
|
+
testResult?: string;
|
|
16
22
|
}
|
|
17
23
|
export interface SimulationOptions {
|
|
18
24
|
scenario: SimulationScenario;
|
|
25
|
+
query?: string;
|
|
19
26
|
maxExchanges: number;
|
|
27
|
+
expectedTool?: Record<string, {
|
|
28
|
+
equal: number;
|
|
29
|
+
}>;
|
|
20
30
|
onMessage?: (message: AgentMessage) => void;
|
|
21
31
|
}
|
|
22
32
|
export interface SimulationResult {
|
|
@@ -25,6 +35,11 @@ export interface SimulationResult {
|
|
|
25
35
|
error: string;
|
|
26
36
|
execution: ExecutionResult;
|
|
27
37
|
exchangeCount: number;
|
|
38
|
+
messages: AgentMessage[];
|
|
39
|
+
toolValidation?: {
|
|
40
|
+
passed: boolean;
|
|
41
|
+
errors: string[];
|
|
42
|
+
};
|
|
28
43
|
}
|
|
29
44
|
export interface ExecutionContext {
|
|
30
45
|
agentContext: AgenticContext;
|
|
@@ -9,12 +9,17 @@ export declare function loadScenario(ticketPath: string): {
|
|
|
9
9
|
};
|
|
10
10
|
/**
|
|
11
11
|
* Construire SimulationScenario à partir d'un ticket PRSolver (rétrocompatibilité)
|
|
12
|
-
* Permet de surcharger tous les champs avec custom
|
|
12
|
+
* Permet de surcharger tous les champs avec custom
|
|
13
|
+
* Note: Cette fonction retourne un scenario SANS query - il faut la passer séparément à executeSimulation
|
|
13
14
|
*/
|
|
14
15
|
export declare function buildScenarioFromTicket(ticketPath: string, clientType: 'locataire' | 'proprietaire', persona?: string, // PERSONA_PATIENT | PERSONA_PRESSE | PERSONA_ENERVE
|
|
15
|
-
custom?: Partial<SimulationScenario>):
|
|
16
|
+
custom?: Partial<SimulationScenario>): {
|
|
17
|
+
scenario: SimulationScenario;
|
|
18
|
+
query: string;
|
|
19
|
+
};
|
|
16
20
|
/**
|
|
17
21
|
* Construire SimulationScenario générique directement
|
|
22
|
+
* Supporte l'ancien format (testGoals, testEnd, etc.) pour rétrocompatibilité
|
|
18
23
|
*/
|
|
19
24
|
export declare function buildGenericScenario(scenario: SimulationScenario): SimulationScenario;
|
|
20
25
|
export { PERSONA_PATIENT, PERSONA_PRESSE, PERSONA_ENERVE };
|