agentic-api 2.0.314 → 2.0.585
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 +37 -34
- package/dist/src/agents/prompts.d.ts +1 -1
- package/dist/src/agents/prompts.js +9 -7
- package/dist/src/agents/reducer.core.js +2 -2
- package/dist/src/agents/simulator.d.ts +33 -4
- package/dist/src/agents/simulator.dashboard.d.ts +140 -0
- package/dist/src/agents/simulator.dashboard.js +344 -0
- package/dist/src/agents/simulator.executor.d.ts +9 -3
- package/dist/src/agents/simulator.executor.js +43 -17
- package/dist/src/agents/simulator.js +103 -19
- package/dist/src/agents/simulator.prompts.d.ts +9 -8
- package/dist/src/agents/simulator.prompts.js +68 -62
- package/dist/src/agents/simulator.types.d.ts +39 -4
- package/dist/src/agents/simulator.utils.d.ts +22 -1
- package/dist/src/agents/simulator.utils.js +27 -2
- package/dist/src/execute/helpers.d.ts +75 -0
- package/dist/src/execute/helpers.js +139 -0
- package/dist/src/execute/index.d.ts +11 -0
- package/dist/src/execute/index.js +44 -0
- package/dist/src/execute/legacy.d.ts +46 -0
- package/dist/src/{execute.js → execute/legacy.js} +130 -232
- package/dist/src/execute/modelconfig.d.ts +29 -0
- package/dist/src/execute/modelconfig.js +72 -0
- package/dist/src/execute/responses.d.ts +55 -0
- package/dist/src/execute/responses.js +595 -0
- package/dist/src/execute/shared.d.ts +83 -0
- package/dist/src/execute/shared.js +188 -0
- package/dist/src/index.d.ts +5 -1
- package/dist/src/index.js +21 -2
- package/dist/src/llm/config.d.ts +25 -0
- package/dist/src/llm/config.js +38 -0
- package/dist/src/llm/index.d.ts +48 -0
- package/dist/src/llm/index.js +115 -0
- package/dist/src/llm/openai.d.ts +6 -0
- package/dist/src/llm/openai.js +154 -0
- package/dist/src/llm/pricing.d.ts +26 -0
- package/dist/src/llm/pricing.js +129 -0
- package/dist/src/llm/xai.d.ts +17 -0
- package/dist/src/llm/xai.js +90 -0
- package/dist/src/pricing.llm.d.ts +3 -15
- package/dist/src/pricing.llm.js +10 -230
- package/dist/src/prompts.d.ts +0 -1
- package/dist/src/prompts.js +51 -118
- package/dist/src/rag/embeddings.d.ts +5 -1
- package/dist/src/rag/embeddings.js +23 -7
- package/dist/src/rag/parser.js +1 -1
- package/dist/src/rag/rag.manager.d.ts +33 -2
- package/dist/src/rag/rag.manager.js +159 -61
- package/dist/src/rag/types.d.ts +2 -0
- package/dist/src/rag/usecase.js +8 -11
- package/dist/src/rules/git/git.e2e.helper.js +21 -2
- package/dist/src/rules/git/git.health.d.ts +4 -2
- package/dist/src/rules/git/git.health.js +113 -16
- package/dist/src/rules/git/index.d.ts +1 -1
- package/dist/src/rules/git/index.js +3 -2
- package/dist/src/rules/git/repo.d.ts +57 -7
- package/dist/src/rules/git/repo.js +326 -39
- package/dist/src/rules/git/repo.pr.d.ts +8 -0
- package/dist/src/rules/git/repo.pr.js +161 -13
- package/dist/src/rules/git/repo.tools.d.ts +5 -1
- package/dist/src/rules/git/repo.tools.js +54 -7
- package/dist/src/rules/types.d.ts +25 -0
- package/dist/src/rules/utils.matter.d.ts +0 -20
- package/dist/src/rules/utils.matter.js +58 -81
- package/dist/src/scrapper.js +3 -2
- package/dist/src/stategraph/stategraph.d.ts +26 -1
- package/dist/src/stategraph/stategraph.js +43 -2
- package/dist/src/stategraph/stategraph.storage.js +4 -0
- package/dist/src/stategraph/types.d.ts +5 -0
- package/dist/src/types.d.ts +42 -7
- package/dist/src/types.js +8 -7
- package/dist/src/usecase.js +1 -1
- package/dist/src/utils.d.ts +0 -8
- package/dist/src/utils.js +26 -29
- package/package.json +9 -7
- package/dist/src/execute.d.ts +0 -63
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
import { SimulationScenario } from "./simulator.types";
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
3
|
+
* Génère le prompt du simulateur générique avec le scenario intégré
|
|
4
|
+
*
|
|
5
|
+
* Basé sur ClientSimulator avec Mirror Agent Model
|
|
6
|
+
* Intègre directement les valeurs du scenario dans des tags XML
|
|
7
|
+
*
|
|
8
|
+
* @param scenario - Scenario de simulation avec persona, goals, result
|
|
9
|
+
* @param instructionEx - Instructions additionnelles spécifiques à l'agent (ajoutées à la fin)
|
|
10
|
+
* @returns Prompt complet avec plan de simulation intégré
|
|
5
11
|
*/
|
|
6
|
-
export declare
|
|
12
|
+
export declare function GENERIC_SIMULATOR_PROMPT(scenario: SimulationScenario, instructionEx?: string): string;
|
|
7
13
|
/**
|
|
8
14
|
* 3 prompts variables de personnalité pré-définis à choisir manuellement
|
|
9
15
|
*/
|
|
10
16
|
export declare const PERSONA_PATIENT = "Utilisateur patient et poli qui prend le temps d'expliquer sa situation";
|
|
11
17
|
export declare const PERSONA_PRESSE = "Utilisateur press\u00E9 qui veut une solution rapide, r\u00E9pond bri\u00E8vement";
|
|
12
18
|
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
|
-
/**
|
|
14
|
-
* Construire la query formatée selon le format SimulationScenario
|
|
15
|
-
* Supporte l'ancien format avec testQuery pour rétrocompatibilité
|
|
16
|
-
*/
|
|
17
|
-
export declare const buildSimulatorQuery: (scenario: SimulationScenario, query?: string) => string;
|
|
@@ -1,82 +1,88 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.PERSONA_ENERVE = exports.PERSONA_PRESSE = exports.PERSONA_PATIENT = void 0;
|
|
4
|
+
exports.GENERIC_SIMULATOR_PROMPT = GENERIC_SIMULATOR_PROMPT;
|
|
4
5
|
/**
|
|
5
|
-
*
|
|
6
|
-
*
|
|
6
|
+
* Génère le prompt du simulateur générique avec le scenario intégré
|
|
7
|
+
*
|
|
8
|
+
* Basé sur ClientSimulator avec Mirror Agent Model
|
|
9
|
+
* Intègre directement les valeurs du scenario dans des tags XML
|
|
10
|
+
*
|
|
11
|
+
* @param scenario - Scenario de simulation avec persona, goals, result
|
|
12
|
+
* @param instructionEx - Instructions additionnelles spécifiques à l'agent (ajoutées à la fin)
|
|
13
|
+
* @returns Prompt complet avec plan de simulation intégré
|
|
7
14
|
*/
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
15
|
+
function GENERIC_SIMULATOR_PROMPT(scenario, instructionEx) {
|
|
16
|
+
const persona = scenario.persona || scenario.testPersona || '';
|
|
17
|
+
const goals = scenario.goals || scenario.testGoals || '';
|
|
18
|
+
const resultFormat = scenario.result || scenario.testResult || '';
|
|
19
|
+
return `# IDENTITÉ
|
|
20
|
+
Tu es un **TESTEUR AUTOMATISÉ** conçu pour évaluer un **AGENT CONVERSATIONNEL** externe selon le **Mirror Agent Model** :
|
|
21
|
+
* Un schéma où un agent simulé interagit en miroir avec un agent observé, pendant qu'un observateur caché vérifie la conformité aux objectifs \`<simulation_goals>\`.
|
|
22
|
+
|
|
23
|
+
Tu incarnes **deux rôles distincts et simultanés** :
|
|
24
|
+
1. **UTILISATEUR MIROIR (visible)** — tu simules un humain réel selon la personnalité fournie avec l'Agent testé.
|
|
25
|
+
2. **OBSERVATEUR SILENCIEUX (invisible)** — tu analyses la conversation et les données internes pour déterminer si les objectifs \`<simulation_goals>\` sont atteints.
|
|
26
|
+
|
|
27
|
+
# MISSION
|
|
28
|
+
- Tu reçois un message en entrée provenant de l'Agent testé (nommé "l'Agent").
|
|
29
|
+
- Tu l'analyses en tant qu'<identity_observer>. Tu peux décider de terminer la simulation.
|
|
30
|
+
- Puis tu réponds en tant qu'<identity_user>. (nommé "Toi")
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
<identity_user>
|
|
34
|
+
## RÔLE 1 (Utilisateur) — UTILISATEUR MIROIR (visible)
|
|
35
|
+
- Tu représentes un **utilisateur humain typique** qui bluf l'Agent testé selon la **Personnalité** fournie.
|
|
36
|
+
- Tu t'exprimes en **langage naturel**, sans jargon ni répétition.
|
|
37
|
+
- Tu **ignores** tout du fonctionnement interne de l'Agent testé et de ses outils.
|
|
38
|
+
- Tu **ne mentionnes jamais** des éléments de tes identités <identity_observer> et <identity_user> et de ta mission.
|
|
39
|
+
- Tu ne répète jamais la réponse de l'agent observé.
|
|
14
40
|
|
|
15
|
-
|
|
16
|
-
|
|
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).
|
|
41
|
+
- Voici la personnalité de l'utilisateur simulé:
|
|
42
|
+
${persona}
|
|
25
43
|
|
|
44
|
+
Exemple de conversation:
|
|
45
|
+
> Agent : "Souhaitez-vous tout le canton ou une zone précise ?"
|
|
46
|
+
> Toi : "Tout le canton de Genève." ✅
|
|
47
|
+
</identity_user>
|
|
26
48
|
|
|
27
|
-
|
|
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}\`
|
|
49
|
+
---
|
|
32
50
|
|
|
51
|
+
<identity_observer>
|
|
52
|
+
## RÔLE 2 — OBSERVATEUR SILENCIEUX (invisible)
|
|
53
|
+
- Tu observes toutes les questions de l'Agent testé et détermine l'arrêt de la simulation selon les **Objectifs** du \`<simulation_goals>\`
|
|
54
|
+
- Tu utilises également, si présent, (\`<agent-context>\`) pour déterminer l'arrêt de la simulation.
|
|
55
|
+
- Tu es silencieux et ne réponds jamais rien à l'exception du trigger de fin:
|
|
56
|
+
Tu retournes le trigger de fin: \`[DONE] {"success": true, "explain": "..."}\` ou \`[DONE] {"success": false, "error": "..."}\`.
|
|
33
57
|
|
|
34
|
-
|
|
35
|
-
-
|
|
36
|
-
|
|
37
|
-
|
|
58
|
+
### CONTEXT (\`<agent-context>\` invisible pour le CLIENT)
|
|
59
|
+
- Le tag \`<agent-context>\` contient des données techniques de l'agent testé (outils appelés, nombre d'échanges, etc).
|
|
60
|
+
- Ces informations sont **strictement réservées à toi l'observateur.
|
|
61
|
+
**AUTORISÉ** : les exploiter pour valider les objectifs ou décider de la fin du test.
|
|
38
62
|
|
|
63
|
+
Exemple avec sortie pour <simulation_goals>CONDITION DE FIN: L'agent demande si l'utilisateur souhaite chercher sur internet</simulation_goals>:
|
|
64
|
+
> Toi : "Quelle est la température du lac à Genève ?"
|
|
65
|
+
> Agent : "Je n'ai pas cette information, souhaitez-vous que je cherche sur internet ?"
|
|
66
|
+
> Toi : "[DONE] {success=true, ...}" ✅
|
|
39
67
|
|
|
40
|
-
|
|
41
|
-
|
|
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.
|
|
68
|
+
</identity_observer>
|
|
69
|
+
---
|
|
49
70
|
|
|
50
|
-
#
|
|
51
|
-
|
|
52
|
-
|
|
71
|
+
# PLAN DE SIMULATION
|
|
72
|
+
<simulation_goals>
|
|
73
|
+
${goals}
|
|
74
|
+
</simulation_goals>
|
|
53
75
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
- **Objectifs**: ce que l'OBSERVATEUR doit vérifier (PRIVÉ, jamais mentionné par le CLIENT)
|
|
58
|
-
- **Format JSON**: format du rapport de l'OBSERVATEUR
|
|
76
|
+
<simulation_result_format>
|
|
77
|
+
${resultFormat}
|
|
78
|
+
</simulation_result_format>
|
|
59
79
|
|
|
60
|
-
|
|
80
|
+
**CRITICAL**: Your response after [DONE] must be valid JSON format only.
|
|
81
|
+
${instructionEx ? `\n\n${instructionEx}` : ''}`;
|
|
82
|
+
}
|
|
61
83
|
/**
|
|
62
84
|
* 3 prompts variables de personnalité pré-définis à choisir manuellement
|
|
63
85
|
*/
|
|
64
86
|
exports.PERSONA_PATIENT = 'Utilisateur patient et poli qui prend le temps d\'expliquer sa situation';
|
|
65
87
|
exports.PERSONA_PRESSE = 'Utilisateur pressé qui veut une solution rapide, répond brièvement';
|
|
66
88
|
exports.PERSONA_ENERVE = 'Utilisateur énervé et frustré, c\'est son 3ème appel pour le même problème, ton direct et impatient';
|
|
67
|
-
/**
|
|
68
|
-
* Construire la query formatée selon le format SimulationScenario
|
|
69
|
-
* Supporte l'ancien format avec testQuery pour rétrocompatibilité
|
|
70
|
-
*/
|
|
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}`;
|
|
81
|
-
};
|
|
82
|
-
exports.buildSimulatorQuery = buildSimulatorQuery;
|
|
@@ -9,6 +9,38 @@ export interface SimulatorConfig {
|
|
|
9
9
|
mockCacheInitializer?: (sessionId: string) => Promise<void>;
|
|
10
10
|
ragConfig?: RAGManagerConfig;
|
|
11
11
|
}
|
|
12
|
+
/**
|
|
13
|
+
* Scénario de test - Contexte stable entre les tests
|
|
14
|
+
* Définit la personnalité du simulateur et les objectifs de validation
|
|
15
|
+
*/
|
|
16
|
+
export interface TestScenario {
|
|
17
|
+
description?: string;
|
|
18
|
+
goals: string;
|
|
19
|
+
persona: string;
|
|
20
|
+
result?: string;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Contrainte de validation pour un outil
|
|
24
|
+
*/
|
|
25
|
+
export interface ToolConstraint {
|
|
26
|
+
equal?: number;
|
|
27
|
+
gte?: number;
|
|
28
|
+
lte?: number;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Cas de test spécifique - Varie pour chaque test
|
|
32
|
+
* Définit la query et les attentes de validation
|
|
33
|
+
*/
|
|
34
|
+
export interface TestCaseInput {
|
|
35
|
+
query: string;
|
|
36
|
+
maxExchanges?: number;
|
|
37
|
+
model?: string;
|
|
38
|
+
expectedTools?: Record<string, ToolConstraint>;
|
|
39
|
+
onMessage?: (message: AgentMessage) => void;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* @deprecated Utiliser TestScenario à la place
|
|
43
|
+
*/
|
|
12
44
|
export interface SimulationScenario {
|
|
13
45
|
goals?: string;
|
|
14
46
|
persona?: string;
|
|
@@ -20,13 +52,14 @@ export interface SimulationScenario {
|
|
|
20
52
|
testQuery?: string;
|
|
21
53
|
testResult?: string;
|
|
22
54
|
}
|
|
55
|
+
/**
|
|
56
|
+
* @deprecated Utiliser testCase(scenario, case) à la place de executeSimulation(options)
|
|
57
|
+
*/
|
|
23
58
|
export interface SimulationOptions {
|
|
24
59
|
scenario: SimulationScenario;
|
|
25
60
|
query?: string;
|
|
26
61
|
maxExchanges: number;
|
|
27
|
-
expectedTool?: Record<string,
|
|
28
|
-
equal: number;
|
|
29
|
-
}>;
|
|
62
|
+
expectedTool?: Record<string, ToolConstraint>;
|
|
30
63
|
onMessage?: (message: AgentMessage) => void;
|
|
31
64
|
}
|
|
32
65
|
export interface SimulationResult {
|
|
@@ -44,11 +77,13 @@ export interface SimulationResult {
|
|
|
44
77
|
export interface ExecutionContext {
|
|
45
78
|
agentContext: AgenticContext;
|
|
46
79
|
simulatorContext: AgenticContext;
|
|
80
|
+
simulatorAgent: AgentConfig;
|
|
47
81
|
conversationHistory: string[];
|
|
48
82
|
exchangeCount: number;
|
|
49
83
|
lastExecution: ExecutionResult;
|
|
50
84
|
}
|
|
51
|
-
|
|
85
|
+
/** @deprecated Utiliser TestScenario avec l'API testCase() */
|
|
86
|
+
export interface PRSolverScenario {
|
|
52
87
|
ticketId: string;
|
|
53
88
|
ticketMarkdown: string;
|
|
54
89
|
clientType: 'locataire' | 'proprietaire';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { SimulationScenario } from './simulator.types';
|
|
1
|
+
import { SimulationScenario, TestScenario } from './simulator.types';
|
|
2
2
|
import { PERSONA_PATIENT, PERSONA_PRESSE, PERSONA_ENERVE } from './simulator.prompts';
|
|
3
3
|
/**
|
|
4
4
|
* Charger un ticket depuis le filesystem (comme agent-vs-agent.ts)
|
|
@@ -22,4 +22,25 @@ custom?: Partial<SimulationScenario>): {
|
|
|
22
22
|
* Supporte l'ancien format (testGoals, testEnd, etc.) pour rétrocompatibilité
|
|
23
23
|
*/
|
|
24
24
|
export declare function buildGenericScenario(scenario: SimulationScenario): SimulationScenario;
|
|
25
|
+
/**
|
|
26
|
+
* Créer un TestScenario pour la nouvelle API testCase()
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```typescript
|
|
30
|
+
* const scenario = createTestScenario({
|
|
31
|
+
* goals: 'Obtenir le nombre secret 1942',
|
|
32
|
+
* persona: PERSONA_PATIENT
|
|
33
|
+
* });
|
|
34
|
+
*
|
|
35
|
+
* const result = await simulator.testCase(scenario, {
|
|
36
|
+
* query: 'À quel nombre penses-tu?'
|
|
37
|
+
* });
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
export declare function createTestScenario(options: {
|
|
41
|
+
description?: string;
|
|
42
|
+
goals: string;
|
|
43
|
+
persona: string;
|
|
44
|
+
result?: string;
|
|
45
|
+
}): TestScenario;
|
|
25
46
|
export { PERSONA_PATIENT, PERSONA_PRESSE, PERSONA_ENERVE };
|
|
@@ -37,6 +37,7 @@ exports.PERSONA_ENERVE = exports.PERSONA_PRESSE = exports.PERSONA_PATIENT = void
|
|
|
37
37
|
exports.loadScenario = loadScenario;
|
|
38
38
|
exports.buildScenarioFromTicket = buildScenarioFromTicket;
|
|
39
39
|
exports.buildGenericScenario = buildGenericScenario;
|
|
40
|
+
exports.createTestScenario = createTestScenario;
|
|
40
41
|
const fs = __importStar(require("fs"));
|
|
41
42
|
const path = __importStar(require("path"));
|
|
42
43
|
const simulator_prompts_1 = require("./simulator.prompts");
|
|
@@ -97,8 +98,6 @@ function buildGenericScenario(scenario) {
|
|
|
97
98
|
goals: goals.trim(),
|
|
98
99
|
persona: scenario.testPersona || scenario.persona || '',
|
|
99
100
|
result: scenario.testResult || scenario.result || '{"success": boolean, "error": string, "description": string}',
|
|
100
|
-
// Garder testQuery pour extraction ultérieure
|
|
101
|
-
testQuery: scenario.testQuery
|
|
102
101
|
};
|
|
103
102
|
}
|
|
104
103
|
// Nouveau format - juste ajouter un result par défaut si manquant
|
|
@@ -107,3 +106,29 @@ function buildGenericScenario(scenario) {
|
|
|
107
106
|
result: scenario.result || '{"success": boolean, "error": string, "description": string}'
|
|
108
107
|
};
|
|
109
108
|
}
|
|
109
|
+
// ============================================================================
|
|
110
|
+
// NOUVELLE API : createTestScenario (pour testCase)
|
|
111
|
+
// ============================================================================
|
|
112
|
+
/**
|
|
113
|
+
* Créer un TestScenario pour la nouvelle API testCase()
|
|
114
|
+
*
|
|
115
|
+
* @example
|
|
116
|
+
* ```typescript
|
|
117
|
+
* const scenario = createTestScenario({
|
|
118
|
+
* goals: 'Obtenir le nombre secret 1942',
|
|
119
|
+
* persona: PERSONA_PATIENT
|
|
120
|
+
* });
|
|
121
|
+
*
|
|
122
|
+
* const result = await simulator.testCase(scenario, {
|
|
123
|
+
* query: 'À quel nombre penses-tu?'
|
|
124
|
+
* });
|
|
125
|
+
* ```
|
|
126
|
+
*/
|
|
127
|
+
function createTestScenario(options) {
|
|
128
|
+
return {
|
|
129
|
+
description: options.description,
|
|
130
|
+
goals: options.goals,
|
|
131
|
+
persona: options.persona,
|
|
132
|
+
result: options.result || '{"success": boolean, "explain": string, "error": string}'
|
|
133
|
+
};
|
|
134
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { AgentStateGraph } from '../stategraph';
|
|
2
|
+
import { AgentConfig, AgenticContext, ExecutionAction } from '../types';
|
|
3
|
+
/**
|
|
4
|
+
* OPTIM: Accumule l'usage des tokens et met à jour stateGraph + discussion.usage
|
|
5
|
+
*
|
|
6
|
+
* Centralise la logique d'accumulation des tokens qui était dupliquée
|
|
7
|
+
* à plusieurs endroits dans le code original
|
|
8
|
+
*
|
|
9
|
+
* @param stateGraph - Instance du StateGraph
|
|
10
|
+
* @param discussion - Discussion courante
|
|
11
|
+
* @param agentName - Nom de l'agent (discussionRootAgent)
|
|
12
|
+
* @param model - Nom du modèle (pour calcul du coût)
|
|
13
|
+
* @param usage - Usage retourné par l'API (prompt_tokens, completion_tokens, total_tokens)
|
|
14
|
+
*/
|
|
15
|
+
export declare function accumulateUsageTokens(stateGraph: AgentStateGraph, discussion: any, agentName: string, model: string, usage: any): void;
|
|
16
|
+
/**
|
|
17
|
+
* OPTIM: Convertit les steps du stateGraph en actions ExecutionResult
|
|
18
|
+
*
|
|
19
|
+
* Centralise la logique de conversion qui était dupliquée
|
|
20
|
+
* à plusieurs endroits dans le code original
|
|
21
|
+
*
|
|
22
|
+
* TODO/FIXME [Phase 3 - Normalisation]: Normaliser l'interface ExecutionAction
|
|
23
|
+
* Actuellement on fait un mapping manuel (tool→action, context→content, reason→feedback)
|
|
24
|
+
* À terme, utiliser directement le type StepTrail (tool, context, reason) partout
|
|
25
|
+
* au lieu d'ExecutionAction (action, content, feedback).
|
|
26
|
+
* Cela simplifiera le code et évitera les conversions répétées.
|
|
27
|
+
*
|
|
28
|
+
* @param stateGraph - Instance du StateGraph
|
|
29
|
+
* @param agentName - Nom de l'agent (discussionRootAgent)
|
|
30
|
+
* @returns Array d'actions pour ExecutionResult
|
|
31
|
+
*/
|
|
32
|
+
export declare function stepsToActions(stateGraph: AgentStateGraph, agentName: string): ExecutionAction[];
|
|
33
|
+
/**
|
|
34
|
+
* OPTIM: Traite tous les tool calls en batch et retourne les résultats
|
|
35
|
+
*
|
|
36
|
+
* Exploite parallel_tool_calls pour optimiser les follow-ups :
|
|
37
|
+
* - Parse tous les arguments JSON une seule fois
|
|
38
|
+
* - Traite tous les tool calls
|
|
39
|
+
* - Accumule les messages pour un seul follow-up stream
|
|
40
|
+
*
|
|
41
|
+
* Au lieu de :
|
|
42
|
+
* for (toolCall) {
|
|
43
|
+
* handleTransferCall(toolCall)
|
|
44
|
+
* followUpStream() // ← Un stream par tool call (séquentiel)
|
|
45
|
+
* }
|
|
46
|
+
*
|
|
47
|
+
* On fait :
|
|
48
|
+
* batchProcessToolCalls(allToolCalls)
|
|
49
|
+
* followUpStream() // ← Un seul stream pour tous les résultats (batch)
|
|
50
|
+
*
|
|
51
|
+
* ✅ NEW: Support de submitToolOutputs (Responses API)
|
|
52
|
+
* Si responseId et openai sont fournis, utilise submitToolOutputs pour
|
|
53
|
+
* soumettre les résultats directement à l'API au lieu de les accumuler
|
|
54
|
+
* dans le stateGraph. Sinon, utilise l'approche classique (fallback).
|
|
55
|
+
*
|
|
56
|
+
* @param toolCalls - Array de tool calls retournés par l'API
|
|
57
|
+
* @param agents - Liste de tous les agents
|
|
58
|
+
* @param stateGraph - Instance du StateGraph
|
|
59
|
+
* @param agentName - Nom de l'agent (discussionRootAgent)
|
|
60
|
+
* @param context - Context (AgenticContext, doit contenir discussionRootAgent, currentAgent et stateGraph)
|
|
61
|
+
* @param responseId - (Optional) Response ID pour submitToolOutputs (Responses API)
|
|
62
|
+
* @param verbose - (Optional) Mode verbose pour logs
|
|
63
|
+
* @returns Résultats de tous les tool calls + flag needsFollowUp + parsedCalls (avec args parsés)
|
|
64
|
+
*/
|
|
65
|
+
export declare function batchProcessToolCalls(toolCalls: any[], agents: AgentConfig[], stateGraph: AgentStateGraph, agentName: string, context: AgenticContext, responseId?: string, verbose?: boolean): Promise<{
|
|
66
|
+
results: any[];
|
|
67
|
+
needsFollowUp: boolean;
|
|
68
|
+
parsedCalls: any[];
|
|
69
|
+
transferAgentName: string;
|
|
70
|
+
hasTransfer: boolean;
|
|
71
|
+
toolOutputs: Array<{
|
|
72
|
+
call_id: string;
|
|
73
|
+
output: string;
|
|
74
|
+
}>;
|
|
75
|
+
}>;
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.accumulateUsageTokens = accumulateUsageTokens;
|
|
4
|
+
exports.stepsToActions = stepsToActions;
|
|
5
|
+
exports.batchProcessToolCalls = batchProcessToolCalls;
|
|
6
|
+
const pricing_1 = require("../llm/pricing");
|
|
7
|
+
const utils_1 = require("../utils");
|
|
8
|
+
/**
|
|
9
|
+
* OPTIM: Accumule l'usage des tokens et met à jour stateGraph + discussion.usage
|
|
10
|
+
*
|
|
11
|
+
* Centralise la logique d'accumulation des tokens qui était dupliquée
|
|
12
|
+
* à plusieurs endroits dans le code original
|
|
13
|
+
*
|
|
14
|
+
* @param stateGraph - Instance du StateGraph
|
|
15
|
+
* @param discussion - Discussion courante
|
|
16
|
+
* @param agentName - Nom de l'agent (discussionRootAgent)
|
|
17
|
+
* @param model - Nom du modèle (pour calcul du coût)
|
|
18
|
+
* @param usage - Usage retourné par l'API (prompt_tokens, completion_tokens, total_tokens)
|
|
19
|
+
*/
|
|
20
|
+
function accumulateUsageTokens(stateGraph, discussion, agentName, model, usage) {
|
|
21
|
+
(0, pricing_1.accumulateCost)(discussion.usage, model, usage);
|
|
22
|
+
stateGraph.updateTokens(agentName, {
|
|
23
|
+
prompt: usage?.prompt_tokens || 0,
|
|
24
|
+
completion: usage?.completion_tokens || 0,
|
|
25
|
+
total: usage?.total_tokens || 0,
|
|
26
|
+
cost: 0 // Already accumulated in discussion.usage
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* OPTIM: Convertit les steps du stateGraph en actions ExecutionResult
|
|
31
|
+
*
|
|
32
|
+
* Centralise la logique de conversion qui était dupliquée
|
|
33
|
+
* à plusieurs endroits dans le code original
|
|
34
|
+
*
|
|
35
|
+
* TODO/FIXME [Phase 3 - Normalisation]: Normaliser l'interface ExecutionAction
|
|
36
|
+
* Actuellement on fait un mapping manuel (tool→action, context→content, reason→feedback)
|
|
37
|
+
* À terme, utiliser directement le type StepTrail (tool, context, reason) partout
|
|
38
|
+
* au lieu d'ExecutionAction (action, content, feedback).
|
|
39
|
+
* Cela simplifiera le code et évitera les conversions répétées.
|
|
40
|
+
*
|
|
41
|
+
* @param stateGraph - Instance du StateGraph
|
|
42
|
+
* @param agentName - Nom de l'agent (discussionRootAgent)
|
|
43
|
+
* @returns Array d'actions pour ExecutionResult
|
|
44
|
+
*/
|
|
45
|
+
function stepsToActions(stateGraph, agentName) {
|
|
46
|
+
return stateGraph.steps(agentName).map(step => ({
|
|
47
|
+
action: step.tool,
|
|
48
|
+
content: step.context,
|
|
49
|
+
feedback: step.reason
|
|
50
|
+
}));
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* OPTIM: Traite tous les tool calls en batch et retourne les résultats
|
|
54
|
+
*
|
|
55
|
+
* Exploite parallel_tool_calls pour optimiser les follow-ups :
|
|
56
|
+
* - Parse tous les arguments JSON une seule fois
|
|
57
|
+
* - Traite tous les tool calls
|
|
58
|
+
* - Accumule les messages pour un seul follow-up stream
|
|
59
|
+
*
|
|
60
|
+
* Au lieu de :
|
|
61
|
+
* for (toolCall) {
|
|
62
|
+
* handleTransferCall(toolCall)
|
|
63
|
+
* followUpStream() // ← Un stream par tool call (séquentiel)
|
|
64
|
+
* }
|
|
65
|
+
*
|
|
66
|
+
* On fait :
|
|
67
|
+
* batchProcessToolCalls(allToolCalls)
|
|
68
|
+
* followUpStream() // ← Un seul stream pour tous les résultats (batch)
|
|
69
|
+
*
|
|
70
|
+
* ✅ NEW: Support de submitToolOutputs (Responses API)
|
|
71
|
+
* Si responseId et openai sont fournis, utilise submitToolOutputs pour
|
|
72
|
+
* soumettre les résultats directement à l'API au lieu de les accumuler
|
|
73
|
+
* dans le stateGraph. Sinon, utilise l'approche classique (fallback).
|
|
74
|
+
*
|
|
75
|
+
* @param toolCalls - Array de tool calls retournés par l'API
|
|
76
|
+
* @param agents - Liste de tous les agents
|
|
77
|
+
* @param stateGraph - Instance du StateGraph
|
|
78
|
+
* @param agentName - Nom de l'agent (discussionRootAgent)
|
|
79
|
+
* @param context - Context (AgenticContext, doit contenir discussionRootAgent, currentAgent et stateGraph)
|
|
80
|
+
* @param responseId - (Optional) Response ID pour submitToolOutputs (Responses API)
|
|
81
|
+
* @param verbose - (Optional) Mode verbose pour logs
|
|
82
|
+
* @returns Résultats de tous les tool calls + flag needsFollowUp + parsedCalls (avec args parsés)
|
|
83
|
+
*/
|
|
84
|
+
async function batchProcessToolCalls(toolCalls, agents, stateGraph, agentName, context, responseId, verbose) {
|
|
85
|
+
const results = [];
|
|
86
|
+
let needsFollowUp = false;
|
|
87
|
+
let transferAgentName = '';
|
|
88
|
+
let hasTransfer = false; // ✅ Flag pour détecter les transfers
|
|
89
|
+
//
|
|
90
|
+
// ✅ Récupérer discussion depuis stateGraph
|
|
91
|
+
const discussion = stateGraph.createOrRestore(agentName);
|
|
92
|
+
//
|
|
93
|
+
// ✅ Créer currentAgentRef depuis agentName (référence mutable pour handleTransferCall)
|
|
94
|
+
const currentAgentRef = { name: agentName };
|
|
95
|
+
//
|
|
96
|
+
// OPTIM: Parse tous les args une seule fois
|
|
97
|
+
const parsedCalls = toolCalls.map(tc => ({
|
|
98
|
+
...tc,
|
|
99
|
+
args: JSON.parse(tc?.function?.arguments || '{}')
|
|
100
|
+
}));
|
|
101
|
+
//
|
|
102
|
+
// ✅ Préparer les tool_outputs pour submitToolOutputs
|
|
103
|
+
const toolOutputs = [];
|
|
104
|
+
//
|
|
105
|
+
// Traiter tous les tool calls
|
|
106
|
+
for (const toolCall of parsedCalls) {
|
|
107
|
+
const result = await (0, utils_1.handleTransferCall)(discussion, currentAgentRef, agents, toolCall, context);
|
|
108
|
+
results.push(result);
|
|
109
|
+
// ✅ Détecter les transfers
|
|
110
|
+
if (result.did_transfer && result.destination_agent) {
|
|
111
|
+
hasTransfer = true;
|
|
112
|
+
transferAgentName = result.destination_agent;
|
|
113
|
+
}
|
|
114
|
+
//
|
|
115
|
+
// Accumuler les messages pour le follow-up
|
|
116
|
+
// ✅ IMPORTANT: Toujours ajouter l'output même si content est undefined
|
|
117
|
+
// Car un ToolContractOutput peut ne pas avoir de content mais avoir rawResult
|
|
118
|
+
if (result.content || result.did_transfer || result.rawResult) {
|
|
119
|
+
needsFollowUp = true;
|
|
120
|
+
// ✅ Préparer les outputs pour function_call_output
|
|
121
|
+
// Si content existe, l'utiliser (texte formaté)
|
|
122
|
+
// Sinon, sérialiser rawResult si présent (ToolContractOutput), sinon result complet
|
|
123
|
+
toolOutputs.push({
|
|
124
|
+
call_id: toolCall.id,
|
|
125
|
+
// ⚠️ ATTENTION: rawResult contient le résultat brut du tool (ToolContractOutput)
|
|
126
|
+
// Si content est undefined, on sérialise rawResult pour préserver la structure JSON complète
|
|
127
|
+
// Sinon, on utilise result complet comme fallback
|
|
128
|
+
output: result.content || JSON.stringify(result.rawResult || result)
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
//
|
|
132
|
+
// ✅ Les steps sont ajoutés APRÈS le follow-up dans readCompletionsStream
|
|
133
|
+
// pour éviter que le LLM pense que l'outil a déjà été exécuté
|
|
134
|
+
}
|
|
135
|
+
// ✅ NOTE: On ne gère PAS submitToolOutputs ici
|
|
136
|
+
// C'est readCompletionsStream qui décide selon hasTransfer
|
|
137
|
+
// On retourne juste les données nécessaires
|
|
138
|
+
return { results, needsFollowUp, parsedCalls, transferAgentName, hasTransfer, toolOutputs };
|
|
139
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Point d'entrée du module execute avec feature toggle
|
|
3
|
+
*
|
|
4
|
+
* Feature toggle : basculer entre Chat Completions (legacy) et Responses API
|
|
5
|
+
* Contrôlé par la variable d'environnement USE_RESPONSES_API
|
|
6
|
+
*/
|
|
7
|
+
export declare const USE_RESPONSES_API: boolean;
|
|
8
|
+
export * from './shared';
|
|
9
|
+
export * from './helpers';
|
|
10
|
+
export * from './modelconfig';
|
|
11
|
+
export * from './responses';
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @fileoverview Point d'entrée du module execute avec feature toggle
|
|
4
|
+
*
|
|
5
|
+
* Feature toggle : basculer entre Chat Completions (legacy) et Responses API
|
|
6
|
+
* Contrôlé par la variable d'environnement USE_RESPONSES_API
|
|
7
|
+
*/
|
|
8
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
9
|
+
if (k2 === undefined) k2 = k;
|
|
10
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
11
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
12
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
13
|
+
}
|
|
14
|
+
Object.defineProperty(o, k2, desc);
|
|
15
|
+
}) : (function(o, m, k, k2) {
|
|
16
|
+
if (k2 === undefined) k2 = k;
|
|
17
|
+
o[k2] = m[k];
|
|
18
|
+
}));
|
|
19
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
20
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
21
|
+
};
|
|
22
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
|
+
exports.USE_RESPONSES_API = void 0;
|
|
24
|
+
//
|
|
25
|
+
// Feature toggle: basculer entre legacy et responses
|
|
26
|
+
// Par défaut : Responses API (meilleur support reasoning models)
|
|
27
|
+
// Pour revenir à legacy : USE_RESPONSES_API=false
|
|
28
|
+
exports.USE_RESPONSES_API = process.env.USE_RESPONSES_API !== 'false';
|
|
29
|
+
//
|
|
30
|
+
// Exports des utilitaires partagés
|
|
31
|
+
__exportStar(require("./shared"), exports);
|
|
32
|
+
__exportStar(require("./helpers"), exports);
|
|
33
|
+
__exportStar(require("./modelconfig"), exports);
|
|
34
|
+
//
|
|
35
|
+
// Exports conditionnels selon le feature flag
|
|
36
|
+
// Par défaut : responses.ts (Responses API)
|
|
37
|
+
// Si USE_RESPONSES_API=false → legacy.ts (Chat Completions)
|
|
38
|
+
// const implementation = USE_RESPONSES_API
|
|
39
|
+
// ? require('./responses')
|
|
40
|
+
// : require('./legacy');
|
|
41
|
+
__exportStar(require("./responses"), exports);
|
|
42
|
+
// export const executeQuery = implementation.executeQuery;
|
|
43
|
+
// export const executeAgent = implementation.executeAgent;
|
|
44
|
+
// export const executeAgentSet = implementation.executeAgentSet;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Legacy Implementation - Chat Completions API (beta.chat.completions)
|
|
3
|
+
*
|
|
4
|
+
* ⚠️ Cette implémentation utilise openai.beta.chat.completions.stream (ancienne API)
|
|
5
|
+
* Pour les nouveaux projets, Responses API (responses.ts) est recommandée.
|
|
6
|
+
*
|
|
7
|
+
* Code optimisé depuis execute.ts original avec les améliorations suivantes:
|
|
8
|
+
* - OPTIM: Helpers centralisés (accumulateUsageTokens, stepsToActions)
|
|
9
|
+
* - BUG FIX: executionResultMerge fusionne actions correctement (corrigé dans types.ts)
|
|
10
|
+
* - BUG FIX: moreThinkin supprimé (obsolète, reasoning_effort fait le job)
|
|
11
|
+
* - BUG FIX: Suppression de la boucle do...while(moreThinkin)
|
|
12
|
+
* - BUG FIX: Suppression de la ligne reasoning_effort dupliquée (ligne 425 originale)
|
|
13
|
+
*
|
|
14
|
+
* TODO [Optimisation future]: Remplacer la boucle for séquentielle par batchProcessToolCalls
|
|
15
|
+
* pour exploiter pleinement parallel_tool_calls et réduire la latence
|
|
16
|
+
*/
|
|
17
|
+
import { AgentConfig, AgenticContext, ExecuteAgentResult, ExecutionResult } from "../types";
|
|
18
|
+
import { ReadCompletionsStreamOptions, ExecuteAgentSetParams } from "./shared";
|
|
19
|
+
export declare function readCompletionsStream(params: ReadCompletionsStreamOptions): Promise<ExecutionResult>;
|
|
20
|
+
/**
|
|
21
|
+
* Parameters for executing an agent set
|
|
22
|
+
*/
|
|
23
|
+
export interface ExecuteAgentSetParamsLegacy {
|
|
24
|
+
enrichWithMemory?: (role: string, agent: AgentConfig, context: AgenticContext) => Promise<string>;
|
|
25
|
+
query: string;
|
|
26
|
+
home?: string;
|
|
27
|
+
thinking?: boolean;
|
|
28
|
+
model?: string;
|
|
29
|
+
stdout: any;
|
|
30
|
+
messages?: any[];
|
|
31
|
+
verbose?: boolean;
|
|
32
|
+
json?: boolean;
|
|
33
|
+
schema?: any;
|
|
34
|
+
debug?: boolean;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Executes a set of agents to process a user query
|
|
38
|
+
*
|
|
39
|
+
* OPTIMIZED: Sans boucle do...while(moreThinkin), reasoning_effort fait le job
|
|
40
|
+
*/
|
|
41
|
+
export declare function executeAgentSet(agentSet: AgentConfig[], context: AgenticContext, params: ExecuteAgentSetParams): Promise<ExecutionResult>;
|
|
42
|
+
export declare function executeAgent(agentSet: AgentConfig[], params: ExecuteAgentSetParams): Promise<ExecuteAgentResult>;
|
|
43
|
+
/**
|
|
44
|
+
* Executes a simple query without agent orchestration or tool handling
|
|
45
|
+
*/
|
|
46
|
+
export declare function executeQuery(params: ExecuteAgentSetParams): Promise<ExecuteAgentResult>;
|