agentic-api 2.0.491 → 2.0.592

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.
Files changed (57) hide show
  1. package/README.md +37 -34
  2. package/dist/src/agents/job.runner.d.ts +130 -0
  3. package/dist/src/agents/job.runner.js +339 -0
  4. package/dist/src/agents/reducer.core.d.ts +11 -1
  5. package/dist/src/agents/reducer.core.js +76 -86
  6. package/dist/src/agents/reducer.d.ts +1 -0
  7. package/dist/src/agents/reducer.factory.d.ts +46 -0
  8. package/dist/src/agents/reducer.factory.js +154 -0
  9. package/dist/src/agents/reducer.js +1 -0
  10. package/dist/src/agents/simulator.d.ts +26 -1
  11. package/dist/src/agents/simulator.dashboard.d.ts +140 -0
  12. package/dist/src/agents/simulator.dashboard.js +344 -0
  13. package/dist/src/agents/simulator.js +56 -0
  14. package/dist/src/agents/simulator.types.d.ts +38 -6
  15. package/dist/src/agents/simulator.utils.d.ts +22 -1
  16. package/dist/src/agents/simulator.utils.js +27 -0
  17. package/dist/src/execute/helpers.js +2 -2
  18. package/dist/src/execute/modelconfig.d.ts +21 -11
  19. package/dist/src/execute/modelconfig.js +29 -13
  20. package/dist/src/execute/responses.js +8 -7
  21. package/dist/src/index.d.ts +6 -1
  22. package/dist/src/index.js +21 -1
  23. package/dist/src/llm/config.d.ts +25 -0
  24. package/dist/src/llm/config.js +38 -0
  25. package/dist/src/llm/index.d.ts +48 -0
  26. package/dist/src/llm/index.js +115 -0
  27. package/dist/src/llm/openai.d.ts +6 -0
  28. package/dist/src/llm/openai.js +154 -0
  29. package/dist/src/llm/pricing.d.ts +26 -0
  30. package/dist/src/llm/pricing.js +129 -0
  31. package/dist/src/llm/xai.d.ts +17 -0
  32. package/dist/src/llm/xai.js +90 -0
  33. package/dist/src/pricing.llm.d.ts +3 -15
  34. package/dist/src/pricing.llm.js +10 -251
  35. package/dist/src/prompts.d.ts +0 -1
  36. package/dist/src/prompts.js +51 -118
  37. package/dist/src/rag/embeddings.d.ts +5 -1
  38. package/dist/src/rag/embeddings.js +15 -5
  39. package/dist/src/rag/parser.js +1 -1
  40. package/dist/src/rag/rag.manager.d.ts +44 -6
  41. package/dist/src/rag/rag.manager.js +138 -49
  42. package/dist/src/rag/types.d.ts +2 -0
  43. package/dist/src/rag/usecase.js +8 -11
  44. package/dist/src/rules/git/git.health.js +59 -4
  45. package/dist/src/rules/git/repo.d.ts +11 -4
  46. package/dist/src/rules/git/repo.js +64 -18
  47. package/dist/src/rules/git/repo.pr.d.ts +8 -0
  48. package/dist/src/rules/git/repo.pr.js +45 -1
  49. package/dist/src/rules/git/repo.tools.d.ts +5 -1
  50. package/dist/src/rules/git/repo.tools.js +54 -7
  51. package/dist/src/rules/types.d.ts +14 -0
  52. package/dist/src/rules/utils.matter.d.ts +0 -20
  53. package/dist/src/rules/utils.matter.js +42 -74
  54. package/dist/src/scrapper.js +2 -2
  55. package/dist/src/utils.d.ts +0 -8
  56. package/dist/src/utils.js +1 -28
  57. package/package.json +1 -1
@@ -0,0 +1,344 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.SimulatorDashboard = void 0;
7
+ const fs_1 = require("fs");
8
+ const promises_1 = require("fs/promises");
9
+ const readline_1 = require("readline");
10
+ const path_1 = __importDefault(require("path"));
11
+ const simulator_1 = require("./simulator");
12
+ // ============================================================================
13
+ // CLASS: SimulatorDashboard
14
+ // ============================================================================
15
+ class SimulatorDashboard {
16
+ constructor(config) {
17
+ this.config = config;
18
+ this.simulator = null;
19
+ this.abortController = null;
20
+ this._currentOutputPath = null;
21
+ this._currentInputPath = null;
22
+ this.status = this.createInitialStatus();
23
+ }
24
+ /**
25
+ * Chemin du fichier output actuel (ou du dernier run)
26
+ */
27
+ get currentOutputPath() {
28
+ return this._currentOutputPath;
29
+ }
30
+ /**
31
+ * Chemin du fichier input actuel (ou du dernier run)
32
+ */
33
+ get currentInputPath() {
34
+ return this._currentInputPath;
35
+ }
36
+ createInitialStatus() {
37
+ return {
38
+ isRunning: false,
39
+ sessionId: null,
40
+ currentTest: 0,
41
+ totalTests: 0,
42
+ passed: 0,
43
+ failed: 0,
44
+ errors: 0,
45
+ startTime: null,
46
+ lastUpdate: null
47
+ };
48
+ }
49
+ /**
50
+ * Obtenir le status actuel (pour le contrôleur backend)
51
+ */
52
+ getStatus() {
53
+ return { ...this.status };
54
+ }
55
+ /**
56
+ * Vérifier si une exécution est en cours
57
+ */
58
+ isRunning() {
59
+ return this.status.isRunning;
60
+ }
61
+ /**
62
+ * Annuler l'exécution en cours
63
+ */
64
+ abort() {
65
+ if (this.abortController) {
66
+ this.abortController.abort();
67
+ }
68
+ }
69
+ /**
70
+ * Charger un fichier JSON d'entrée
71
+ */
72
+ async loadInputFile(filePath) {
73
+ const content = await (0, promises_1.readFile)(filePath, 'utf-8');
74
+ return JSON.parse(content);
75
+ }
76
+ /**
77
+ * Générer le chemin du fichier output basé sur le fichier input
78
+ * Exemple: tests/my-tests.json → tests/results.my-tests.jsonl
79
+ */
80
+ createOutputPath(inputPath) {
81
+ const dir = path_1.default.dirname(inputPath);
82
+ const basename = path_1.default.basename(inputPath, path_1.default.extname(inputPath));
83
+ return path_1.default.join(dir, `results.${basename}.jsonl`);
84
+ }
85
+ /**
86
+ * Charger les résultats JSONL existants (en cours ou terminés)
87
+ * Supporte le streaming partiel (fichier en cours d'écriture)
88
+ *
89
+ * @param inputPath - Chemin du fichier JSON d'entrée (génère automatiquement le output path)
90
+ * @returns Les lignes parsées ou null si le fichier n'existe pas
91
+ */
92
+ async loadResults(inputPath) {
93
+ // Déterminer le chemin du fichier output
94
+ let outputPath = null;
95
+ if (inputPath) {
96
+ outputPath = this.createOutputPath(inputPath);
97
+ }
98
+ else if (this._currentInputPath) {
99
+ outputPath = this.createOutputPath(this._currentInputPath);
100
+ }
101
+ else if (this._currentOutputPath) {
102
+ outputPath = this._currentOutputPath;
103
+ }
104
+ if (!outputPath || !(0, fs_1.existsSync)(outputPath)) {
105
+ return null;
106
+ }
107
+ return new Promise((resolve, reject) => {
108
+ const lines = [];
109
+ const stream = (0, fs_1.createReadStream)(outputPath, { encoding: 'utf-8' });
110
+ const rl = (0, readline_1.createInterface)({ input: stream, crlfDelay: Infinity });
111
+ rl.on('line', (line) => {
112
+ if (line.trim()) {
113
+ try {
114
+ lines.push(JSON.parse(line));
115
+ }
116
+ catch (e) {
117
+ // Ignorer les lignes mal formées (fichier en cours d'écriture)
118
+ }
119
+ }
120
+ });
121
+ rl.on('close', () => resolve(lines));
122
+ rl.on('error', reject);
123
+ });
124
+ }
125
+ /**
126
+ * Obtenir le résumé des résultats (dernière ligne type='end')
127
+ * @param inputPath - Chemin du fichier JSON d'entrée
128
+ */
129
+ async getResultsSummary(inputPath) {
130
+ const results = await this.loadResults(inputPath);
131
+ if (!results)
132
+ return null;
133
+ const endLine = results.find(r => r.type === 'end');
134
+ return endLine?.summary || null;
135
+ }
136
+ /**
137
+ * Vérifier si les résultats sont complets (contient une ligne 'end')
138
+ * @param inputPath - Chemin du fichier JSON d'entrée
139
+ */
140
+ async isResultsComplete(inputPath) {
141
+ const results = await this.loadResults(inputPath);
142
+ if (!results)
143
+ return false;
144
+ return results.some(r => r.type === 'end');
145
+ }
146
+ /**
147
+ * Exécuter les tests et écrire les résultats en JSONL
148
+ *
149
+ * @param input - Données d'entrée (ou chemin vers fichier JSON)
150
+ * @param outputPath - Chemin du fichier JSONL de sortie
151
+ * @param onLine - Callback optionnel pour chaque ligne JSONL (streaming)
152
+ */
153
+ async run(input, outputPath, onLine) {
154
+ // Stocker et charger l'input si c'est un chemin
155
+ const isInputFile = typeof input === 'string';
156
+ this._currentInputPath = isInputFile ? input : null;
157
+ const data = isInputFile
158
+ ? await this.loadInputFile(input)
159
+ : input;
160
+ // Générer automatiquement le outputPath si input est un fichier
161
+ const resolvedOutputPath = outputPath ?? (isInputFile ? this.createOutputPath(input) : undefined);
162
+ this._currentOutputPath = resolvedOutputPath || null;
163
+ // Initialiser le status
164
+ const sessionId = `session-${Date.now()}`;
165
+ this.status = {
166
+ isRunning: true,
167
+ sessionId,
168
+ currentTest: 0,
169
+ totalTests: data.tests.length,
170
+ passed: 0,
171
+ failed: 0,
172
+ errors: 0,
173
+ startTime: new Date(),
174
+ lastUpdate: new Date()
175
+ };
176
+ // Créer le simulateur avec config mergée
177
+ const mergedConfig = {
178
+ ...this.config,
179
+ ...data.config
180
+ };
181
+ this.simulator = new simulator_1.AgentSimulator(mergedConfig);
182
+ // Créer l'AbortController
183
+ this.abortController = new AbortController();
184
+ // Ouvrir le fichier de sortie si spécifié
185
+ let writeStream = null;
186
+ if (resolvedOutputPath) {
187
+ writeStream = (0, fs_1.createWriteStream)(resolvedOutputPath, { encoding: 'utf-8' });
188
+ }
189
+ const results = [];
190
+ const startTime = Date.now();
191
+ // Helper pour écrire une ligne
192
+ const writeLine = (line) => {
193
+ results.push(line);
194
+ const jsonLine = JSON.stringify(line) + '\n';
195
+ if (writeStream) {
196
+ writeStream.write(jsonLine);
197
+ }
198
+ if (onLine) {
199
+ onLine(line);
200
+ }
201
+ };
202
+ try {
203
+ // Écrire la ligne de début
204
+ writeLine({
205
+ type: 'start',
206
+ timestamp: new Date().toISOString(),
207
+ sessionId,
208
+ totalTests: data.tests.length
209
+ });
210
+ // Exécuter chaque test
211
+ for (let i = 0; i < data.tests.length; i++) {
212
+ // Vérifier si annulé
213
+ if (this.abortController.signal.aborted) {
214
+ break;
215
+ }
216
+ const testCase = data.tests[i];
217
+ const testId = testCase.id || `test-${i}`;
218
+ const testStartTime = Date.now();
219
+ // Mettre à jour le status
220
+ this.status.currentTest = i + 1;
221
+ this.status.lastUpdate = new Date();
222
+ try {
223
+ // Exécuter le test
224
+ const result = await this.simulator.testCase(testCase.scenario, testCase.case);
225
+ // Déterminer le status
226
+ const status = result.success ? 'completed' : 'failed';
227
+ // Mettre à jour les compteurs
228
+ if (result.success) {
229
+ this.status.passed++;
230
+ }
231
+ else {
232
+ this.status.failed++;
233
+ }
234
+ // Écrire le résultat
235
+ writeLine({
236
+ type: 'result',
237
+ timestamp: new Date().toISOString(),
238
+ testId,
239
+ testIndex: i,
240
+ name: testCase.name || testId,
241
+ description: testCase.scenario.description || testCase.scenario.goals,
242
+ query: testCase.case.query,
243
+ status,
244
+ success: result.success,
245
+ message: result.message,
246
+ error: result.error || undefined,
247
+ exchangeCount: result.exchangeCount,
248
+ messages: result.messages,
249
+ duration: Date.now() - testStartTime
250
+ });
251
+ }
252
+ catch (error) {
253
+ // Erreur d'exécution
254
+ this.status.errors++;
255
+ writeLine({
256
+ type: 'error',
257
+ timestamp: new Date().toISOString(),
258
+ testId,
259
+ testIndex: i,
260
+ name: testCase.name || testId,
261
+ description: testCase.scenario.description || testCase.scenario.goals,
262
+ query: testCase.case.query,
263
+ status: 'error',
264
+ success: false,
265
+ error: error.message || String(error),
266
+ duration: Date.now() - testStartTime
267
+ });
268
+ }
269
+ }
270
+ // Écrire la ligne de fin
271
+ writeLine({
272
+ type: 'end',
273
+ timestamp: new Date().toISOString(),
274
+ sessionId,
275
+ summary: {
276
+ total: data.tests.length,
277
+ passed: this.status.passed,
278
+ failed: this.status.failed,
279
+ errors: this.status.errors,
280
+ totalDuration: Date.now() - startTime
281
+ }
282
+ });
283
+ }
284
+ finally {
285
+ // Fermer le stream et attendre la fin de l'écriture
286
+ if (writeStream) {
287
+ await new Promise((resolve, reject) => {
288
+ writeStream.end(() => resolve());
289
+ writeStream.on('error', reject);
290
+ });
291
+ }
292
+ // Reset le status
293
+ this.status.isRunning = false;
294
+ this.status.lastUpdate = new Date();
295
+ this.simulator = null;
296
+ this.abortController = null;
297
+ }
298
+ return results;
299
+ }
300
+ /**
301
+ * Exécuter avec callback de streaming (pour SSE/WebSocket)
302
+ */
303
+ async runWithStream(input, onLine) {
304
+ return this.run(input, undefined, onLine);
305
+ }
306
+ /**
307
+ * Créer un fichier JSON d'exemple pour les tests
308
+ */
309
+ static createExampleInput() {
310
+ return {
311
+ name: "Example Test Suite",
312
+ description: "Exemple de suite de tests pour le simulator",
313
+ tests: [
314
+ {
315
+ id: "test-greeting",
316
+ name: "Test de salutation",
317
+ scenario: {
318
+ goals: "L'agent doit répondre poliment à la salutation",
319
+ persona: "Utilisateur poli et patient"
320
+ },
321
+ case: {
322
+ query: "Bonjour, comment allez-vous?"
323
+ // maxExchanges: 1 par défaut
324
+ // expectedTools: {} par défaut
325
+ }
326
+ },
327
+ {
328
+ id: "test-transfer",
329
+ name: "Test de transfert",
330
+ scenario: {
331
+ goals: "L'agent doit transférer vers l'agent spécialisé",
332
+ persona: "Utilisateur avec une demande spécifique"
333
+ },
334
+ case: {
335
+ query: "J'ai besoin d'aide spécialisée",
336
+ maxExchanges: 3,
337
+ expectedTools: { 'transferAgents': { gte: 1 } }
338
+ }
339
+ }
340
+ ]
341
+ };
342
+ }
343
+ }
344
+ exports.SimulatorDashboard = SimulatorDashboard;
@@ -7,7 +7,63 @@ class AgentSimulator {
7
7
  this.config = config;
8
8
  this.executor = new simulator_executor_1.AgentExecutor(config);
9
9
  }
10
+ // ============================================================================
11
+ // NOUVELLE API : testCase(scenario, case)
12
+ // ============================================================================
10
13
  /**
14
+ * Exécuter un cas de test avec scénario et paramètres séparés
15
+ *
16
+ * @param scenario - Contexte stable (goals, persona, result)
17
+ * @param testCase - Paramètres du test (query, maxExchanges, model, expectedTools)
18
+ * @returns SimulationResult
19
+ *
20
+ * @example
21
+ * ```typescript
22
+ * const scenario = {
23
+ * goals: 'Obtenir le nombre secret 1942',
24
+ * persona: PERSONA_PATIENT,
25
+ * result: '{"success": boolean, "error": string}'
26
+ * };
27
+ *
28
+ * const result = await simulator.testCase(scenario, {
29
+ * query: 'À quel nombre penses-tu?',
30
+ * maxExchanges: 3, // défaut: 1 (oneshot)
31
+ * expectedTools: { 'transferAgents': { equal: 1 } } // défaut: {}
32
+ * });
33
+ * ```
34
+ */
35
+ async testCase(scenario, testCase) {
36
+ // Appliquer les défauts
37
+ const resolvedCase = {
38
+ query: testCase.query,
39
+ maxExchanges: testCase.maxExchanges ?? 1, // Défaut: 1 (oneshot)
40
+ expectedTools: testCase.expectedTools ?? {}, // Défaut: pas de validation
41
+ model: testCase.model,
42
+ onMessage: testCase.onMessage
43
+ };
44
+ // TODO: Support model override (Phase 2)
45
+ // if (resolvedCase.model) {
46
+ // this.overrideModel(resolvedCase.model);
47
+ // }
48
+ // Convertir TestScenario vers SimulationScenario et déléguer
49
+ return this.executeSimulation({
50
+ scenario: {
51
+ goals: scenario.goals,
52
+ persona: scenario.persona,
53
+ result: scenario.result || '{"success": boolean, "explain": string, "error": string}'
54
+ },
55
+ query: resolvedCase.query,
56
+ maxExchanges: resolvedCase.maxExchanges,
57
+ expectedTool: resolvedCase.expectedTools,
58
+ onMessage: resolvedCase.onMessage
59
+ });
60
+ }
61
+ // ============================================================================
62
+ // ANCIENNE API : executeSimulation(options) - deprecated
63
+ // ============================================================================
64
+ /**
65
+ * @deprecated Utiliser testCase(scenario, case) à la place
66
+ *
11
67
  * Exécuter la simulation complète
12
68
  *
13
69
  * Architecture :
@@ -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,15 +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
- gte?: number;
30
- lte?: number;
31
- }>;
62
+ expectedTool?: Record<string, ToolConstraint>;
32
63
  onMessage?: (message: AgentMessage) => void;
33
64
  }
34
65
  export interface SimulationResult {
@@ -51,7 +82,8 @@ export interface ExecutionContext {
51
82
  exchangeCount: number;
52
83
  lastExecution: ExecutionResult;
53
84
  }
54
- export interface TestScenario {
85
+ /** @deprecated Utiliser TestScenario avec l'API testCase() */
86
+ export interface PRSolverScenario {
55
87
  ticketId: string;
56
88
  ticketMarkdown: string;
57
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");
@@ -105,3 +106,29 @@ function buildGenericScenario(scenario) {
105
106
  result: scenario.result || '{"success": boolean, "error": string, "description": string}'
106
107
  };
107
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
+ }
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.accumulateUsageTokens = accumulateUsageTokens;
4
4
  exports.stepsToActions = stepsToActions;
5
5
  exports.batchProcessToolCalls = batchProcessToolCalls;
6
- const pricing_llm_1 = require("../pricing.llm");
6
+ const pricing_1 = require("../llm/pricing");
7
7
  const utils_1 = require("../utils");
8
8
  /**
9
9
  * OPTIM: Accumule l'usage des tokens et met à jour stateGraph + discussion.usage
@@ -18,7 +18,7 @@ const utils_1 = require("../utils");
18
18
  * @param usage - Usage retourné par l'API (prompt_tokens, completion_tokens, total_tokens)
19
19
  */
20
20
  function accumulateUsageTokens(stateGraph, discussion, agentName, model, usage) {
21
- (0, pricing_llm_1.accumulateCost)(discussion.usage, model, usage);
21
+ (0, pricing_1.accumulateCost)(discussion.usage, model, usage);
22
22
  stateGraph.updateTokens(agentName, {
23
23
  prompt: usage?.prompt_tokens || 0,
24
24
  completion: usage?.completion_tokens || 0,
@@ -1,19 +1,29 @@
1
1
  import { AgentModel } from '../types';
2
+ import { LLMProvider } from '../llm';
2
3
  /**
3
4
  * Configuration des modèles pour Chat Completions (legacy) et Responses API
4
5
  *
5
6
  * Gère la configuration des modèles avec migration automatique des paramètres
6
- * selon le provider (OpenAI, xAI) et l'API utilisée (legacy ou Responses)
7
+ * entre les deux APIs.
7
8
  *
8
- * @param model - Alias du modèle (LOW-fast, MEDIUM-fast, HIGH-fast, HIGH-medium, etc.)
9
- * @param custom - Options custom
10
- * @param custom.thinking - Si true, active reasoning_effort élevé (via LLM mapping)
11
- * @param forResponses - Si true, retourne format Responses API avec mappings:
12
- * - reasoning_effort reasoning: { effort }
13
- * - verbosity → text.verbosity
14
- * @returns Configuration du modèle
9
+ * @param model - Alias du modèle (ex: "LOW", "MEDIUM", "HIGH", "EMBEDDING-small", "VISION")
10
+ * @param custom - Options personnalisées (provider, thinking, temperature, etc.)
11
+ * @param custom.provider - Provider à utiliser ('openai' | 'xai'), default: LLM_PROVIDER env
12
+ * @param custom.thinking - Active le mode raisonnement (reasoning_effort: high)
13
+ * @param forResponses - Si true, adapte pour l'API Responses (sinon Chat Completions)
15
14
  *
16
- * NOTE: Pour GPT-5, temperature est toujours fixée à 1
17
- * NOTE: reasoning_effort est géré automatiquement par LLM() selon le provider
15
+ * @example
16
+ * // Modèle par défaut
17
+ * const config = modelConfig("MEDIUM");
18
+ *
19
+ * // Forcer OpenAI pour embeddings
20
+ * const config = modelConfig("EMBEDDING-small", { provider: 'openai' });
21
+ *
22
+ * // Vision avec xAI
23
+ * const config = modelConfig("VISION", { provider: 'xai' });
18
24
  */
19
- export declare function modelConfig(model: string, custom?: any, forResponses?: boolean): AgentModel;
25
+ export declare function modelConfig(model: string, custom?: {
26
+ provider?: LLMProvider;
27
+ thinking?: boolean;
28
+ [key: string]: any;
29
+ }, forResponses?: boolean): AgentModel;
@@ -1,27 +1,36 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.modelConfig = modelConfig;
4
- const utils_1 = require("../utils");
5
- const pricing_llm_1 = require("../pricing.llm");
4
+ const llm_1 = require("../llm");
5
+ const pricing_1 = require("../llm/pricing");
6
6
  /**
7
7
  * Configuration des modèles pour Chat Completions (legacy) et Responses API
8
8
  *
9
9
  * Gère la configuration des modèles avec migration automatique des paramètres
10
- * selon le provider (OpenAI, xAI) et l'API utilisée (legacy ou Responses)
10
+ * entre les deux APIs.
11
11
  *
12
- * @param model - Alias du modèle (LOW-fast, MEDIUM-fast, HIGH-fast, HIGH-medium, etc.)
13
- * @param custom - Options custom
14
- * @param custom.thinking - Si true, active reasoning_effort élevé (via LLM mapping)
15
- * @param forResponses - Si true, retourne format Responses API avec mappings:
16
- * - reasoning_effort reasoning: { effort }
17
- * - verbosity → text.verbosity
18
- * @returns Configuration du modèle
12
+ * @param model - Alias du modèle (ex: "LOW", "MEDIUM", "HIGH", "EMBEDDING-small", "VISION")
13
+ * @param custom - Options personnalisées (provider, thinking, temperature, etc.)
14
+ * @param custom.provider - Provider à utiliser ('openai' | 'xai'), default: LLM_PROVIDER env
15
+ * @param custom.thinking - Active le mode raisonnement (reasoning_effort: high)
16
+ * @param forResponses - Si true, adapte pour l'API Responses (sinon Chat Completions)
19
17
  *
20
- * NOTE: Pour GPT-5, temperature est toujours fixée à 1
21
- * NOTE: reasoning_effort est géré automatiquement par LLM() selon le provider
18
+ * @example
19
+ * // Modèle par défaut
20
+ * const config = modelConfig("MEDIUM");
21
+ *
22
+ * // Forcer OpenAI pour embeddings
23
+ * const config = modelConfig("EMBEDDING-small", { provider: 'openai' });
24
+ *
25
+ * // Vision avec xAI
26
+ * const config = modelConfig("VISION", { provider: 'xai' });
22
27
  */
23
28
  function modelConfig(model, custom, forResponses = false) {
29
+ //
30
+ // Extraire et supprimer les paramètres spéciaux
31
+ const provider = custom?.provider || (0, llm_1.getDefaultProvider)();
24
32
  const thinking = custom?.thinking || false;
33
+ delete custom?.provider;
25
34
  delete custom?.thinking;
26
35
  const defaultOptions = Object.assign({
27
36
  stream_options: { "include_usage": true },
@@ -29,7 +38,14 @@ function modelConfig(model, custom, forResponses = false) {
29
38
  //
30
39
  // Get mapping based on provider (OpenAI vs xAI)
31
40
  // LLM() applique automatiquement reasoning_effort si thinking=true
32
- const mapping = (0, pricing_llm_1.LLM)((0, utils_1.openaiInstance)(), thinking);
41
+ const mapping = (0, pricing_1.LLM)(provider, thinking);
42
+ //
43
+ // Vérifier que le modèle existe pour ce provider
44
+ if (!mapping[model]) {
45
+ const availableModels = Object.keys(mapping).join(', ');
46
+ throw new Error(`Model "${model}" not available for provider "${provider}". ` +
47
+ `Available models: ${availableModels}`);
48
+ }
33
49
  const options = Object.assign({}, mapping[model], defaultOptions);
34
50
  //
35
51
  // Pour Responses API : mapper vers la nouvelle structure et filtrer les paramètres incompatibles