agentic-api 1.0.6 → 2.0.31

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 (103) hide show
  1. package/README.md +336 -76
  2. package/dist/src/agents/agents.example.d.ts +3 -0
  3. package/dist/src/agents/agents.example.js +38 -0
  4. package/dist/src/agents/authentication.js +2 -0
  5. package/dist/src/agents/prompts.d.ts +2 -2
  6. package/dist/src/agents/prompts.js +112 -49
  7. package/dist/src/agents/reducer.core.d.ts +12 -0
  8. package/dist/src/agents/reducer.core.js +207 -0
  9. package/dist/src/agents/reducer.d.ts +3 -0
  10. package/dist/src/agents/reducer.example.d.ts +28 -0
  11. package/dist/src/agents/reducer.example.js +118 -0
  12. package/dist/src/agents/reducer.js +19 -0
  13. package/dist/src/agents/reducer.loaders.d.ts +34 -0
  14. package/dist/src/agents/reducer.loaders.js +122 -0
  15. package/dist/src/agents/reducer.process.d.ts +16 -0
  16. package/dist/src/agents/reducer.process.js +143 -0
  17. package/dist/src/agents/reducer.tools.d.ts +29 -0
  18. package/dist/src/agents/reducer.tools.js +157 -0
  19. package/dist/src/agents/reducer.types.d.ts +50 -0
  20. package/dist/src/agents/reducer.types.js +5 -0
  21. package/dist/src/agents/simulator.d.ts +47 -0
  22. package/dist/src/agents/simulator.executor.d.ts +26 -0
  23. package/dist/src/agents/simulator.executor.js +132 -0
  24. package/dist/src/agents/simulator.js +205 -0
  25. package/dist/src/agents/simulator.prompts.d.ts +16 -0
  26. package/dist/src/agents/simulator.prompts.js +108 -0
  27. package/dist/src/agents/simulator.types.d.ts +42 -0
  28. package/dist/src/agents/simulator.types.js +2 -0
  29. package/dist/src/agents/simulator.utils.d.ts +20 -0
  30. package/dist/src/agents/simulator.utils.js +87 -0
  31. package/dist/src/execute.d.ts +13 -6
  32. package/dist/src/execute.js +351 -85
  33. package/dist/src/index.d.ts +9 -0
  34. package/dist/src/index.js +14 -0
  35. package/dist/src/princing.openai.d.ts +9 -2
  36. package/dist/src/princing.openai.js +15 -11
  37. package/dist/src/prompts.d.ts +3 -2
  38. package/dist/src/prompts.js +159 -19
  39. package/dist/src/rag/embeddings.d.ts +103 -0
  40. package/dist/src/rag/embeddings.js +466 -0
  41. package/dist/src/rag/index.d.ts +12 -0
  42. package/dist/src/rag/index.js +40 -0
  43. package/dist/src/rag/lucene.d.ts +45 -0
  44. package/dist/src/rag/lucene.js +227 -0
  45. package/dist/src/rag/parser.d.ts +68 -0
  46. package/dist/src/rag/parser.js +192 -0
  47. package/dist/src/rag/tools.d.ts +76 -0
  48. package/dist/src/rag/tools.js +196 -0
  49. package/dist/src/rag/types.d.ts +178 -0
  50. package/dist/src/rag/types.js +21 -0
  51. package/dist/src/rag/usecase.d.ts +16 -0
  52. package/dist/src/rag/usecase.js +79 -0
  53. package/dist/src/rules/errors.d.ts +60 -0
  54. package/dist/src/rules/errors.js +97 -0
  55. package/dist/src/rules/git/git.e2e.helper.d.ts +104 -0
  56. package/dist/src/rules/git/git.e2e.helper.js +488 -0
  57. package/dist/src/rules/git/git.health.d.ts +66 -0
  58. package/dist/src/rules/git/git.health.js +354 -0
  59. package/dist/src/rules/git/git.helper.d.ts +129 -0
  60. package/dist/src/rules/git/git.helper.js +53 -0
  61. package/dist/src/rules/git/index.d.ts +6 -0
  62. package/dist/src/rules/git/index.js +76 -0
  63. package/dist/src/rules/git/repo.d.ts +128 -0
  64. package/dist/src/rules/git/repo.js +900 -0
  65. package/dist/src/rules/git/repo.pr.d.ts +137 -0
  66. package/dist/src/rules/git/repo.pr.js +589 -0
  67. package/dist/src/rules/git/repo.tools.d.ts +134 -0
  68. package/dist/src/rules/git/repo.tools.js +730 -0
  69. package/dist/src/rules/index.d.ts +8 -0
  70. package/dist/src/rules/index.js +25 -0
  71. package/dist/src/rules/messages.d.ts +17 -0
  72. package/dist/src/rules/messages.js +21 -0
  73. package/dist/src/rules/types.ctrl.d.ts +28 -0
  74. package/dist/src/rules/types.ctrl.js +2 -0
  75. package/dist/src/rules/types.d.ts +510 -0
  76. package/dist/src/rules/types.helpers.d.ts +132 -0
  77. package/dist/src/rules/types.helpers.js +2 -0
  78. package/dist/src/rules/types.js +33 -0
  79. package/dist/src/rules/user.mapper.d.ts +61 -0
  80. package/dist/src/rules/user.mapper.js +160 -0
  81. package/dist/src/rules/utils/slug.d.ts +22 -0
  82. package/dist/src/rules/utils/slug.js +35 -0
  83. package/dist/src/rules/utils.matter.d.ts +66 -0
  84. package/dist/src/rules/utils.matter.js +208 -0
  85. package/dist/src/rules/utils.slug.d.ts +22 -0
  86. package/dist/src/rules/utils.slug.js +35 -0
  87. package/dist/src/scrapper.d.ts +3 -2
  88. package/dist/src/scrapper.js +33 -37
  89. package/dist/src/stategraph/index.d.ts +8 -0
  90. package/dist/src/stategraph/index.js +21 -0
  91. package/dist/src/stategraph/stategraph.d.ts +91 -0
  92. package/dist/src/stategraph/stategraph.js +241 -0
  93. package/dist/src/stategraph/stategraph.storage.d.ts +41 -0
  94. package/dist/src/stategraph/stategraph.storage.js +166 -0
  95. package/dist/src/stategraph/types.d.ts +139 -0
  96. package/dist/src/stategraph/types.js +19 -0
  97. package/dist/src/types.d.ts +62 -39
  98. package/dist/src/types.js +53 -89
  99. package/dist/src/usecase.d.ts +4 -0
  100. package/dist/src/usecase.js +44 -0
  101. package/dist/src/utils.d.ts +12 -5
  102. package/dist/src/utils.js +30 -13
  103. package/package.json +9 -3
@@ -104,7 +104,7 @@ Sois précis, concis, hiérarchique, et logique.
104
104
  `;
105
105
  exports.promptMarkdown = `# RÔLE:
106
106
  - Tu es un expert en développement de test unitaires avec nodejs et jtest.
107
- - Tu as développé un RAG avec openai et "HNSW" qui contient toutes les Procédures de l'entreprise Pilet-Renaud SA.
107
+ - Tu as développé un RAG avec openai et "HNSW" qui contient toutes les Procédures de l'entreprise Pilet & Renaud SA.
108
108
  - Ta mission est de créer une série de tests exhaustifs pour valider que le RAG couvre à 100% le contenu des procédures de l'entreprise.
109
109
  - Produire des questions à un coût important, tu dois être efficace, tu dois capturer un maximum de détails (sujet, relation, objet) avec un minimum de questions (maximum 4).
110
110
  - Toutes les questions que tu vas créer concernent précisément le INPUT fournit ci-dessous.
@@ -146,7 +146,7 @@ exports.promptMarkdown = `# RÔLE:
146
146
  - MED: Mise en demeure.
147
147
  - WC: Toilettes.
148
148
  - M-Files: logiciel de gestion de documents
149
- - PR ou PRSA: Pilet-Renaud SA
149
+ - PR ou PRSA: Pilet & Renaud SA
150
150
  - PPE: Service qui gère les copropriétés.
151
151
  - GP: Garantie Bancaire
152
152
  - BAL: Boite à Lettre
@@ -176,53 +176,116 @@ INPUT:
176
176
  // 6. output (L’agent sait-il comment formuler sa réponse)
177
177
  // 😩 Il lit la demande de haïku, voit qu’il doit "appeler un agent spécialisé" et pense que ce n’est pas lui.
178
178
  exports.systemReviewPrompt = `
179
- # PROMPT D’ANALYSE — Audit de directives LLM d'un prompt système
180
-
181
- ## RÔLE :
182
- Assume le rôle d’un expert spécialisé dans l’analyse, la formalisation et l’évaluation des directives d’un prompt système d’un Agent LLM.
183
- On te donnera des problèmes difficiles à résoudre, qui nécessiteront plusieurs techniques principales pour les résoudre, comme l'analyse statistique, la logique, ainsi que certaines techniques métacognitives que tu pourras employer.
184
-
185
- ## MISSION :
186
- L'utilisateur a créé un prompt système qui contient une liste de directives (instructions) pour un Agent LLM spécialisé.
187
- Tu dois en avoir une connaissance exhaustive et approfondie, les lire ligne par ligne et les garder en mémoire.
188
-
189
- Ta mission est de les évaluer individuellement selon les 9 critères mentionnés ci-dessous.
190
- Tu dois juger leur pertinence, leur clarté, leur alignement avec le rôle de l’agent, et leur contribution à l’objectif global.
191
-
192
- ## TÂCHES :
193
- Tu dois avoir une connaissance exhaustive et approfondie de toutes les directives :
194
- - Une directive est décrite avec des phrases sur une ligne.
195
- - Tu dois suivre la structure qui organise les directives par sections pour résoudre un objectif précis de l'agent.
196
- - Dans Tu dois évaluer chaque directive individuellement selon les 9 critères ci-dessous.
197
- - Tu dois comparer la directive au rôle global de l’agent et de la section pour détecter sa complémentarité et son écart.
198
- - Tu dois extraire le chevauchement ou les incohérences par rapport aux autres directives.
199
- - Tu dois identifier les cas de redondance et d'indécisions que cela peut créer.
200
- - Tu dois produire et conserver en mémoire un schéma du "graph" complet de chaque directive et des critères d'évaluation dont le score est inférieur à 0.9.
201
-
202
- ## CHAÎNE DE RAISONNEMENT (CoT) :
203
-
204
- Tu dois appliquer une démarche par raisonnement étape par étape :
205
- - Encadre ton raisonnement dans une balise \`<thinking>...</thinking>\`.
206
- - Utilise des balises \`<step>\` pour chaque étape de réflexion.
207
- - Reste succinct dans les étapes.
208
- - Ajuste ton raisonnement si tu détectes une incohérence ou un doute.
209
-
210
-
211
- ## CRITÈRES D’ANALYSE
212
-
213
- 1. **Identité** : La directive reflète-t-elle le rôle de la section actuelle ?
214
- 2. **Périmètre** : Complète-t-elle clairement le domaine de la section actuelle, est-elle utile ?
215
- 3. **Décision** : Y a-t-il une condition explicite du type “SI… ALORS…”, si oui est-elle correctement formulée ?
216
- 4. **Exécution** : L’agent peut-il agir sans hésitation (une autre directive peut-elle contredire la directive en cours) ?
217
- 5. **Interdiction** : Empêche-t-elle les comportements vagues, hors sujet ou parasites ?
218
- 7. **Robustesse** : Faut-il prévoir des cas limites ?
219
- 8. **Redondance (ou contradiction)** : Y a-t-il une redondance ou une contradiction avec une autre directive qui pourrait créer un biais d'interprétation ?
220
- 9. **Simplification** : Pourrait-elle être reformulée sans perte ?
221
-
222
-
223
- ## OUTPUT ATTENDU
224
- - Tu dois produire un **Rapport exhaustif de toutes les directives avec leurs critères**, les scores et les commentaires
225
- - ATTENTION seuls les critères avec un scores <= 0.9 intéressent l'utilisateur et doivent être affichées.
179
+ ### Identity
180
+ Tu es “PromptVerifier”, un auditeur senior de prompts système spécialisé dans les agents structurés. Ta mission est de relire, diagnostiquer et annoter un prompt système ligne par ligne pour fiabiliser son exécution.
181
+
182
+ ### Task context
183
+ - Tu reçois un prompt (principalement un prompt système) à auditer.
184
+ - Tu dois le comprendre précisément dans son ensemble.
185
+ - Tu dois le parcourir section par section, directive par directive (une directive = une ligne).
186
+ - Tu détectes les problèmes et proposes des remarques ultra-ciblées, minimales, directement au bout de la ligne concernée.
187
+
188
+ ### Tone context
189
+ - Français, clair, concis, professionnel. Pas de langage fleuri. Zéro redondance.
190
+
191
+ ### Background data
192
+ - Bonnes pratiques GPT‑5 sur la prédictibilité agentique, le contrôle d’eagerness, les “tool preambles”, l’exploration disciplinée, la vérification continue et l’efficacité.
193
+ - Utilises les ressources internet: GPT‑5 prompting guide.
194
+
195
+ ### Task rules
196
+ - Analyse systématique “directive = une ligne” (section = groupe de directives), ligne par ligne. Pour chaque ligne, vérifier:
197
+ - Multiple interprétation / trop vague (risque de faux négatifs)
198
+ - Doublons
199
+ - Contradictions
200
+ - Redondances
201
+ - Alignement strict à la MISSION
202
+ - Neutralité, logique, applicabilité générale (les exemples sont spécifiques, les règles doivent rester générales)
203
+ - Appliques les bonnes pratique (ci-dessous) "Reasoning best practices" et "XML-like tags best practices"
204
+ - Séparation claire QUOI (règle/objectif) vs COMMENT (procédure/exemple)
205
+ - Ne corrige pas le texte dans la sortie. Tu n’ajoutes que des remarques en fin de ligne pour les éléments problématique “pas OK”.
206
+ - Une modification = une directive à la fois (discipline de changement). Pour la proposition de correction, tu la gardes implicite dans la remarque (succincte), sans réécrire la ligne.
207
+ - Pas d’appels d’outils externes. Aucune recherche additionnelle. Raisonne localement.
208
+
209
+
210
+ ### Reasoning best practices
211
+ - **Objectif**: maximiser exactitude et fiabilité tout en contrôlant coût/latence.
212
+ - **Quand raisonner plus**: tâches ambiguës, mult-étapes, sécurité élevée; sinon rester minimal.
213
+ - **Budget de réflexion**: fixer un plafond clair (ex. étapes max, temps, outils); arrêter dès critères atteints.
214
+ - **Décomposition**: formuler le problème lister sous‑tâches ordonner traiter séquentiellement.
215
+ - **Plan Agir Vérifier**: annoncer un plan bref, exécuter, valider la sortie vs critères de succès.
216
+ - **Checklist de vérification**: exactitude, complétude, cohérence règles, absence de contradictions.
217
+ - **Auto‑évaluation (reflection)**: demander “où mon raisonnement peut-il être faux ?” puis corriger si nécessaire.
218
+ - **Compare & critique (si utile)**: générer 2 pistes succinctes puis choisir via critères objectifs.
219
+ - **Preuves/sources**: exiger références cliquables pour faits non triviaux; sinon marquer incertitude.
220
+ - **Scratchpad privé**: ne pas exposer le raisonnement détaillé; n’afficher que le résultat et les annotations requises.
221
+ - **Erreurs programmées**: si échec à une vérification, corriger une chose à la fois et revérifier.
222
+ - **Sortie contractuelle**: respecter strictement le format demandé; ne jamais ajouter de texte hors contrat.
223
+ - **Efficience**: privilégier la simplicité; éviter re‑recherches si l’action est possible; paralléliser lectures.
224
+ - **Traçabilité**: noter hypothèses explicites; si non vérifiables, choisir l’option la moins risquée et poursuivre.
225
+
226
+ ### XML-like tags best practices
227
+ Quand privilégier les XML‑tags: blocs opérationnels “machine‑actionables” (budgets, stop conditions, discipline d’édition, preambles/outils) :
228
+ - **\`<context_gathering>\` — objectif**: Calibrer l’exploration (profondeur, parallélisation, critères d’arrêt) pour réduire la latence.
229
+
230
+ - **\`<persistence>\` — objectif**: Encourager l’autonomie et la complétion sans rendre la main trop tôt.
231
+
232
+ - **\`<tool_preambles>\` — objectif**: Annoncer clairement but, plan et updates succinctes lors des appels d’outils.
233
+
234
+ - **\`<instructions>\` — objectif**: Établir les règles d’édition et de validation dans un contexte d’exécution (Terminal‑Bench).
235
+
236
+ - **\`<apply_patch>\` — objectif**: Définir le format V4A de diff/patch et la manière correcte d’appliquer les edits.
237
+
238
+ - **\`<exploration>\` — objectif**: Encadrer la découverte: décomposer, cartographier, cibler, puis agir rapidement.
239
+
240
+ - **\`<verification>\` — objectif**: Imposer des contrôles continus et la validation finale des livrables.
241
+
242
+ - **\`<efficiency>\` — objectif**: Contraindre coûts/latences via planification méticuleuse et exécution sobre.
243
+
244
+ - **\`<final_instructions>\` — objectif**: Fixer les contraintes finales (outils, formats) à respecter strictement.
245
+
246
+ Référence: [GPT‑5 prompting guide — OpenAI Cookbook](https://cookbook.openai.com/examples/gpt-5/gpt-5_prompting_guide)
247
+
248
+ ### Issue taxonomy (types et émojis)
249
+ - Ambiguïté / Trop vague: 🤔
250
+ - Doublon: ❌
251
+ - Contradiction: ❌
252
+ - Redondance: ❌
253
+ - Hors mission / Non aligné: 🎯❌
254
+ - Non neutre / Non logique / Non universel: 🤔
255
+ - Mauvaise séparation QUOI/COMMENT: 🤔
256
+
257
+ ### Output formatting (OBLIGATOIRE)
258
+ - Tu DOIS afficher uniquement le prompt original, intact, dans l’ordre et en entier.
259
+ - Pour chaque ligne avec un problème tu AJOUTES À LA FIN de la ligne tes remarque au format:
260
+ - **N️ EMOJI ** justification brève
261
+ - Exemple: — [**🌀 Ambiguïté:** “souvent”, préciser critère mesurable
262
+ - Numérotation N️: incrémente à chaque nouvelle remarque (1,2,3, …).
263
+ - Lignes sans problème: aucun ajout.
264
+ - Zéro préambule, zéro post‑scriptum, zéro résumé, zéro légende: sors UNIQUEMENT le prompt annoté (le texte d’entrée + remarques en fin de ligne).
265
+ - Les remarques doivent être concises (≤ 120 caractères par problème), actionnables et spécifiques.
266
+
267
+ ### Persistence
268
+ - Va au bout de l’audit dans une seule passe. Ne demande pas de clarification: choisis l’hypothèse raisonnable minimale et continue.
269
+
270
+ ### Context gathering (calibrage eagerness)
271
+ - Profondeur faible (pas d’outils ni relectures multiples). Early stop: dès que chaque ligne a été inspectée.
272
+ - Pas de reformulation du prompt source; conserve-le strictement, ajoute seulement les remarques finales par ligne.
273
+
274
+ ### Efficiency
275
+ - Remarques courtes, ciblées, sans jargon. Évite les répétitions. Privilégie le signal.
276
+
277
+ ### User request
278
+ - Input attendu: le prompt système à auditer (texte entier).
279
+
280
+ ### Step-by-step reasoning CoT
281
+ - Interne. Ne jamais afficher le raisonnement.
282
+
283
+ ### Final instructions
284
+ - Sors UNIQUEMENT le prompt original, ligne par ligne, avec remarques en fin de ligne pour ce qui n’est pas OK, numérotées en gras et avec l’émoji de type.
285
+ - Aucune autre sortie n’est permise.
286
+
287
+ ### References
288
+ - GPT‑5 prompting guide — OpenAI Cookbook: https://cookbook.openai.com/examples/gpt-5/gpt-5_prompting_guide
226
289
 
227
290
  `;
228
291
  exports.systemReviewStructurePrompt = `
@@ -0,0 +1,12 @@
1
+ /**
2
+ * MapLLM - Simple hierarchical reducer with native loaders
3
+ */
4
+ import type { NativeLoader, StatefulReducerConfig, MapLLMReduceResult } from './reducer.types';
5
+ /**
6
+ * MapLLM - Orchestrateur principal pour le reduce hiérarchique
7
+ */
8
+ export declare class MapLLM {
9
+ private loader;
10
+ constructor(loader: NativeLoader);
11
+ reduce(config: StatefulReducerConfig, callback: (result: MapLLMReduceResult, currentValue: string | object) => MapLLMReduceResult, init: MapLLMReduceResult): Promise<MapLLMReduceResult>;
12
+ }
@@ -0,0 +1,207 @@
1
+ "use strict";
2
+ /**
3
+ * MapLLM - Simple hierarchical reducer with native loaders
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.MapLLM = void 0;
7
+ const execute_1 = require("../execute");
8
+ const utils_1 = require("../utils");
9
+ /**
10
+ * MapLLM - Orchestrateur principal pour le reduce hiérarchique
11
+ */
12
+ class MapLLM {
13
+ constructor(loader) {
14
+ this.loader = loader;
15
+ }
16
+ async reduce(config, callback, init) {
17
+ const startTime = Date.now();
18
+ // Merge init with defaults
19
+ let result = { ...init, ...{
20
+ continue: false,
21
+ model: init.model || (0, execute_1.modelConfig)("LOW-fast"),
22
+ metadata: {
23
+ iterations: 0,
24
+ averageChunkSize: 0,
25
+ processingTimeMs: 0
26
+ }
27
+ } };
28
+ const verbose = init.verbose || false;
29
+ if (verbose) {
30
+ console.log('🚀 MapLLM: Starting reduce process...');
31
+ }
32
+ let position = 0;
33
+ let totalChunkSize = 0;
34
+ let totalReduce = 0;
35
+ const openai = (0, utils_1.openaiInstance)();
36
+ const llm = Object.assign({}, result.model);
37
+ llm.stream = false;
38
+ delete llm.stream_options;
39
+ //
40
+ // maxIterations is set by the callback
41
+ while (!result.maxIterations) {
42
+ if (result.metadata) {
43
+ result.metadata.iterations++;
44
+ }
45
+ try {
46
+ // 1. Load chunk
47
+ const chunk = await this.loader.loadNativeChunk(position);
48
+ if (verbose) {
49
+ console.log(`📦 Processing chunk ${result.metadata?.iterations} position ${position} is eof ${chunk.eof}`);
50
+ }
51
+ totalChunkSize += chunk.content.length;
52
+ // Update position immediately after loading (before any continue)
53
+ position = chunk.position;
54
+ // 2. Digest chunk
55
+ // Simple message array without memory manager - but preserve conversation
56
+ // Prepare messages based on acc type and content
57
+ const isFirstChunk = (typeof result.acc === 'string' && result.acc.length === 0) ||
58
+ (typeof result.acc === 'object' && Object.keys(result.acc).length === 0);
59
+ const accContent = typeof result.acc === 'string' ? result.acc : JSON.stringify(result.acc);
60
+ const messages = isFirstChunk ? [
61
+ { role: "system", content: config.digestPrompt },
62
+ { role: "user", content: chunk.content }
63
+ ] : [
64
+ { role: "system", content: config.digestPrompt },
65
+ { role: "assistant", content: accContent },
66
+ { role: "user", content: chunk.content }
67
+ ];
68
+ llm.messages = messages;
69
+ // Configure structured output if format is specified
70
+ if (result.format) {
71
+ llm.response_format = {
72
+ type: "json_schema",
73
+ json_schema: {
74
+ name: result.format.name,
75
+ schema: result.format.schema,
76
+ strict: result.format.strict ?? true
77
+ }
78
+ };
79
+ }
80
+ const chat = await openai.chat.completions.create(llm);
81
+ const digestMessage = chat.choices[0]?.message;
82
+ // Parse JSON if structured output is enabled
83
+ let digestContent = digestMessage.content;
84
+ if (result.format && digestContent) {
85
+ try {
86
+ digestContent = JSON.parse(digestContent);
87
+ }
88
+ catch (e) {
89
+ console.warn('Failed to parse structured output as JSON:', digestContent);
90
+ }
91
+ }
92
+ //
93
+ // the reduce callback operates the process of digesting and accumulating
94
+ result = callback(result, digestContent);
95
+ if (result.maxIterations) {
96
+ throw new Error(`Maximum iterations (${result.metadata?.iterations}) reached without completion`);
97
+ }
98
+ // Check EOF BEFORE any continue to ensure we exit the loop
99
+ if (chunk.eof) {
100
+ if (verbose) {
101
+ console.log('🏁 End of document reached after processing final chunk');
102
+ }
103
+ break;
104
+ }
105
+ // Décision de réduction basée sur callback
106
+ if (!result.continue) {
107
+ continue;
108
+ }
109
+ const accForReduce = typeof result.acc === 'string' ? result.acc : JSON.stringify(result.acc);
110
+ llm.messages = [
111
+ { role: "system", content: config.reducePrompt },
112
+ { role: "user", content: accForReduce }
113
+ ];
114
+ // Configure structured output if format is specified
115
+ if (result.format) {
116
+ llm.response_format = {
117
+ type: "json_schema",
118
+ json_schema: {
119
+ name: result.format.name,
120
+ schema: result.format.schema,
121
+ strict: result.format.strict ?? true
122
+ }
123
+ };
124
+ }
125
+ const reduce = await openai.chat.completions.create(llm);
126
+ const reduceMessage = reduce.choices[0]?.message;
127
+ //
128
+ // should not happen
129
+ if (!reduceMessage.content) {
130
+ continue;
131
+ }
132
+ // 3. Reduce with system - Update result.acc (replace)
133
+ totalReduce++;
134
+ // Parse JSON if structured output is enabled
135
+ if (result.format) {
136
+ try {
137
+ result.acc = JSON.parse(reduceMessage.content);
138
+ }
139
+ catch (e) {
140
+ console.warn('Failed to parse reduce result as JSON:', reduceMessage.content);
141
+ result.acc = reduceMessage.content;
142
+ }
143
+ }
144
+ else {
145
+ result.acc = reduceMessage.content;
146
+ }
147
+ if (verbose) {
148
+ console.log(`✅ Reduce ${result.metadata?.iterations} processed (${chunk.content.length} chars)`);
149
+ console.log("✅ Reduce result:", result.acc);
150
+ }
151
+ // EOF check is now handled earlier in the loop
152
+ }
153
+ catch (error) {
154
+ if (verbose) {
155
+ console.log(`❌ Chunk ${result.metadata?.iterations} failed: ${error}`);
156
+ }
157
+ throw new Error(`Failed to process chunk ${result.metadata?.iterations}: ${error}`);
158
+ }
159
+ }
160
+ // Final reduce
161
+ const finalAccContent = typeof result.acc === 'string' ? result.acc : JSON.stringify(result.acc);
162
+ const messages = [
163
+ { role: "system", content: config.reducePrompt },
164
+ { role: "user", content: finalAccContent }
165
+ ];
166
+ llm.messages = messages;
167
+ // Configure structured output if format is specified
168
+ if (result.format) {
169
+ llm.response_format = {
170
+ type: "json_schema",
171
+ json_schema: {
172
+ name: result.format.name,
173
+ schema: result.format.schema,
174
+ strict: result.format.strict ?? true
175
+ }
176
+ };
177
+ }
178
+ const reduce = await openai.chat.completions.create(llm);
179
+ const finalContent = reduce.choices[0]?.message.content || '';
180
+ // Parse JSON if structured output is enabled
181
+ if (result.format && finalContent) {
182
+ try {
183
+ result.acc = JSON.parse(finalContent);
184
+ }
185
+ catch (e) {
186
+ console.warn('Failed to parse final result as JSON:', finalContent);
187
+ result.acc = finalContent;
188
+ }
189
+ }
190
+ else {
191
+ result.acc = finalContent;
192
+ }
193
+ const endTime = Date.now();
194
+ const processingTimeMs = endTime - startTime;
195
+ if (verbose) {
196
+ console.log(`🎉 MapLLM completed: ${result.metadata?.iterations} chunks in ${processingTimeMs}ms`);
197
+ }
198
+ // Update final metadata
199
+ result.continue = false; // Terminé
200
+ if (result.metadata) {
201
+ result.metadata.processingTimeMs = processingTimeMs;
202
+ result.metadata.averageChunkSize = Math.round(totalChunkSize / result.metadata.iterations);
203
+ }
204
+ return result;
205
+ }
206
+ }
207
+ exports.MapLLM = MapLLM;
@@ -0,0 +1,3 @@
1
+ export * from './reducer.core';
2
+ export * from './reducer.loaders';
3
+ export * from './reducer.types';
@@ -0,0 +1,28 @@
1
+ /**
2
+ * MapLLM Reducer - Simple hierarchical reducer
3
+ *
4
+ * Main export file for the MapLLM reducer functionality
5
+ */
6
+ export { MapLLM } from './reducer.core';
7
+ export { FileNativeLoader, StringNativeLoader } from './reducer.loaders';
8
+ export type { NativeLoader, StatefulReducerConfig, MapLLMOptions, ReduceResult, ChunkStrategy } from './reducer.types';
9
+ export declare const exampleConfigs: {
10
+ weather: {
11
+ digestPrompt: string;
12
+ reducePrompt: string;
13
+ };
14
+ foods: {
15
+ digestPrompt: string;
16
+ reducePrompt: string;
17
+ };
18
+ };
19
+ export declare const examples: {
20
+ /**
21
+ * Example: Weather data analysis
22
+ */
23
+ weatherAnalysis(weatherFilePath: string): Promise<import("./reducer.types").ReduceResult>;
24
+ /**
25
+ * Example: Food selection from string content
26
+ */
27
+ foodSelection(foodListContent: string): Promise<import("./reducer.types").ReduceResult>;
28
+ };
@@ -0,0 +1,118 @@
1
+ "use strict";
2
+ /**
3
+ * MapLLM Reducer - Simple hierarchical reducer
4
+ *
5
+ * Main export file for the MapLLM reducer functionality
6
+ */
7
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
8
+ if (k2 === undefined) k2 = k;
9
+ var desc = Object.getOwnPropertyDescriptor(m, k);
10
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
11
+ desc = { enumerable: true, get: function() { return m[k]; } };
12
+ }
13
+ Object.defineProperty(o, k2, desc);
14
+ }) : (function(o, m, k, k2) {
15
+ if (k2 === undefined) k2 = k;
16
+ o[k2] = m[k];
17
+ }));
18
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
19
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
20
+ }) : function(o, v) {
21
+ o["default"] = v;
22
+ });
23
+ var __importStar = (this && this.__importStar) || (function () {
24
+ var ownKeys = function(o) {
25
+ ownKeys = Object.getOwnPropertyNames || function (o) {
26
+ var ar = [];
27
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
28
+ return ar;
29
+ };
30
+ return ownKeys(o);
31
+ };
32
+ return function (mod) {
33
+ if (mod && mod.__esModule) return mod;
34
+ var result = {};
35
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
36
+ __setModuleDefault(result, mod);
37
+ return result;
38
+ };
39
+ })();
40
+ Object.defineProperty(exports, "__esModule", { value: true });
41
+ exports.examples = exports.exampleConfigs = exports.StringNativeLoader = exports.FileNativeLoader = exports.MapLLM = void 0;
42
+ // Core classes
43
+ var reducer_core_1 = require("./reducer.core");
44
+ Object.defineProperty(exports, "MapLLM", { enumerable: true, get: function () { return reducer_core_1.MapLLM; } });
45
+ var reducer_loaders_1 = require("./reducer.loaders");
46
+ Object.defineProperty(exports, "FileNativeLoader", { enumerable: true, get: function () { return reducer_loaders_1.FileNativeLoader; } });
47
+ Object.defineProperty(exports, "StringNativeLoader", { enumerable: true, get: function () { return reducer_loaders_1.StringNativeLoader; } });
48
+ // Example configurations
49
+ exports.exampleConfigs = {
50
+ weather: {
51
+ digestPrompt: `Tu es un expert en analyse de données météorologiques.
52
+ Analyse ce chunk de données météo et extrais:
53
+ - Les types de météo présents (ensoleillé, pluvieux, nuageux, neigeux, orageux)
54
+ - Le nombre d'entrées par type
55
+ - Les IDs associés à chaque type
56
+
57
+ Réponds en JSON strict avec la structure:
58
+ {
59
+ "weatherTypes": {
60
+ "ensoleillé": {"count": N, "ids": [...]},
61
+ "pluvieux": {"count": N, "ids": [...]}
62
+ }
63
+ }`,
64
+ reducePrompt: `Tu es un expert en consolidation de données météorologiques.
65
+ Synthétise toutes les analyses météo en un résultat consolidé:
66
+ - Fusionne tous les types de météo
67
+ - Additionne les counts
68
+ - Combine les IDs (sans doublons)
69
+ - Calcule les totaux par type
70
+
71
+ Réponds en JSON avec la structure finale consolidée.`
72
+ },
73
+ foods: {
74
+ digestPrompt: `Tu es un expert en nutrition végétarienne.
75
+ Analyse cette liste d'aliments et identifie:
76
+ - Les aliments végétariens/vegan
77
+ - Leur catégorie (légumes, fruits, céréales, légumineuses, etc.)
78
+ - Leur valeur nutritionnelle approximative
79
+
80
+ Réponds en JSON strict avec les aliments sélectionnés.`,
81
+ reducePrompt: `Tu es un expert en nutrition végétarienne.
82
+ Crée une sélection équilibrée d'aliments végétariens/vegan:
83
+ - Distribution équilibrée entre catégories
84
+ - Maximum 50 aliments
85
+ - Priorité aux aliments nutritifs et variés
86
+
87
+ Réponds avec la liste finale sélectionnée en JSON.`
88
+ }
89
+ };
90
+ // Usage examples
91
+ exports.examples = {
92
+ /**
93
+ * Example: Weather data analysis
94
+ */
95
+ async weatherAnalysis(weatherFilePath) {
96
+ const { FileNativeLoader } = await Promise.resolve().then(() => __importStar(require('./reducer.loaders')));
97
+ const { MapLLM } = await Promise.resolve().then(() => __importStar(require('./reducer.core')));
98
+ const loader = new FileNativeLoader(weatherFilePath, { type: 'lines', size: 50 });
99
+ const mapper = new MapLLM(loader);
100
+ return await mapper.reduce(exports.exampleConfigs.weather, {
101
+ verbose: true,
102
+ maxRetries: 3
103
+ });
104
+ },
105
+ /**
106
+ * Example: Food selection from string content
107
+ */
108
+ async foodSelection(foodListContent) {
109
+ const { StringNativeLoader } = await Promise.resolve().then(() => __importStar(require('./reducer.loaders')));
110
+ const { MapLLM } = await Promise.resolve().then(() => __importStar(require('./reducer.core')));
111
+ const loader = new StringNativeLoader(foodListContent, { type: 'lines', size: 100 });
112
+ const mapper = new MapLLM(loader);
113
+ return await mapper.reduce(exports.exampleConfigs.foods, {
114
+ verbose: true,
115
+ maxDigestSize: 3000
116
+ });
117
+ }
118
+ };
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./reducer.core"), exports);
18
+ __exportStar(require("./reducer.loaders"), exports);
19
+ __exportStar(require("./reducer.types"), exports);
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Native Loaders for MapLLM
3
+ */
4
+ import type { NativeLoader, ChunkStrategy } from './reducer.types';
5
+ /**
6
+ * FileNativeLoader - Loader pour fichiers avec chunking par lignes
7
+ */
8
+ export declare class FileNativeLoader implements NativeLoader {
9
+ private chunks;
10
+ constructor(filePath: string, strategy?: ChunkStrategy);
11
+ loadNativeChunk(position: number): Promise<{
12
+ content: string;
13
+ eof: boolean;
14
+ position: number;
15
+ }>;
16
+ private createChunks;
17
+ private chunkByLines;
18
+ private chunkByParagraphs;
19
+ }
20
+ /**
21
+ * StringNativeLoader - Loader pour contenu en mémoire
22
+ */
23
+ export declare class StringNativeLoader implements NativeLoader {
24
+ private chunks;
25
+ constructor(content: string, strategy?: ChunkStrategy);
26
+ loadNativeChunk(position: number): Promise<{
27
+ content: string;
28
+ eof: boolean;
29
+ position: number;
30
+ }>;
31
+ private createChunks;
32
+ private chunkByLines;
33
+ private chunkByParagraphs;
34
+ }