agentic-api 2.0.31 → 2.0.491

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 (102) hide show
  1. package/dist/src/agents/agents.example.js +21 -22
  2. package/dist/src/agents/authentication.js +1 -2
  3. package/dist/src/agents/prompts.d.ts +5 -4
  4. package/dist/src/agents/prompts.js +44 -87
  5. package/dist/src/agents/reducer.core.d.ts +24 -2
  6. package/dist/src/agents/reducer.core.js +125 -35
  7. package/dist/src/agents/reducer.loaders.d.ts +55 -1
  8. package/dist/src/agents/reducer.loaders.js +114 -1
  9. package/dist/src/agents/reducer.types.d.ts +45 -2
  10. package/dist/src/agents/semantic.js +1 -2
  11. package/dist/src/agents/simulator.d.ts +11 -3
  12. package/dist/src/agents/simulator.executor.d.ts +14 -4
  13. package/dist/src/agents/simulator.executor.js +81 -23
  14. package/dist/src/agents/simulator.js +128 -42
  15. package/dist/src/agents/simulator.prompts.d.ts +9 -7
  16. package/dist/src/agents/simulator.prompts.js +66 -86
  17. package/dist/src/agents/simulator.types.d.ts +23 -5
  18. package/dist/src/agents/simulator.utils.d.ts +7 -2
  19. package/dist/src/agents/simulator.utils.js +31 -11
  20. package/dist/src/agents/system.js +1 -2
  21. package/dist/src/execute/helpers.d.ts +75 -0
  22. package/dist/src/execute/helpers.js +139 -0
  23. package/dist/src/execute/index.d.ts +11 -0
  24. package/dist/src/execute/index.js +44 -0
  25. package/dist/src/execute/legacy.d.ts +46 -0
  26. package/dist/src/execute/legacy.js +460 -0
  27. package/dist/src/execute/modelconfig.d.ts +19 -0
  28. package/dist/src/execute/modelconfig.js +56 -0
  29. package/dist/src/execute/responses.d.ts +55 -0
  30. package/dist/src/execute/responses.js +594 -0
  31. package/dist/src/execute/shared.d.ts +83 -0
  32. package/dist/src/execute/shared.js +188 -0
  33. package/dist/src/index.d.ts +1 -1
  34. package/dist/src/index.js +2 -2
  35. package/dist/src/{princing.openai.d.ts → pricing.llm.d.ts} +6 -0
  36. package/dist/src/pricing.llm.js +255 -0
  37. package/dist/src/prompts.d.ts +13 -4
  38. package/dist/src/prompts.js +221 -114
  39. package/dist/src/rag/embeddings.d.ts +36 -18
  40. package/dist/src/rag/embeddings.js +131 -128
  41. package/dist/src/rag/index.d.ts +5 -5
  42. package/dist/src/rag/index.js +14 -17
  43. package/dist/src/rag/parser.d.ts +2 -1
  44. package/dist/src/rag/parser.js +11 -14
  45. package/dist/src/rag/rag.examples.d.ts +27 -0
  46. package/dist/src/rag/rag.examples.js +151 -0
  47. package/dist/src/rag/rag.manager.d.ts +383 -0
  48. package/dist/src/rag/rag.manager.js +1390 -0
  49. package/dist/src/rag/types.d.ts +128 -12
  50. package/dist/src/rag/types.js +100 -1
  51. package/dist/src/rag/usecase.d.ts +37 -0
  52. package/dist/src/rag/usecase.js +96 -7
  53. package/dist/src/rules/git/git.e2e.helper.js +22 -2
  54. package/dist/src/rules/git/git.health.d.ts +61 -2
  55. package/dist/src/rules/git/git.health.js +333 -11
  56. package/dist/src/rules/git/index.d.ts +2 -2
  57. package/dist/src/rules/git/index.js +13 -1
  58. package/dist/src/rules/git/repo.d.ts +160 -0
  59. package/dist/src/rules/git/repo.js +777 -0
  60. package/dist/src/rules/git/repo.pr.js +117 -13
  61. package/dist/src/rules/git/repo.tools.d.ts +22 -1
  62. package/dist/src/rules/git/repo.tools.js +50 -1
  63. package/dist/src/rules/types.d.ts +27 -14
  64. package/dist/src/rules/utils.matter.d.ts +0 -4
  65. package/dist/src/rules/utils.matter.js +35 -7
  66. package/dist/src/scrapper.d.ts +15 -22
  67. package/dist/src/scrapper.js +58 -110
  68. package/dist/src/stategraph/index.d.ts +1 -1
  69. package/dist/src/stategraph/stategraph.d.ts +56 -2
  70. package/dist/src/stategraph/stategraph.js +134 -6
  71. package/dist/src/stategraph/stategraph.storage.js +8 -0
  72. package/dist/src/stategraph/types.d.ts +27 -0
  73. package/dist/src/types.d.ts +46 -9
  74. package/dist/src/types.js +8 -7
  75. package/dist/src/usecase.d.ts +11 -2
  76. package/dist/src/usecase.js +27 -35
  77. package/dist/src/utils.d.ts +32 -18
  78. package/dist/src/utils.js +87 -129
  79. package/package.json +10 -3
  80. package/dist/src/agents/digestor.test.d.ts +0 -1
  81. package/dist/src/agents/digestor.test.js +0 -45
  82. package/dist/src/agents/reducer.example.d.ts +0 -28
  83. package/dist/src/agents/reducer.example.js +0 -118
  84. package/dist/src/agents/reducer.process.d.ts +0 -16
  85. package/dist/src/agents/reducer.process.js +0 -143
  86. package/dist/src/agents/reducer.tools.d.ts +0 -29
  87. package/dist/src/agents/reducer.tools.js +0 -157
  88. package/dist/src/agents/simpleExample.d.ts +0 -3
  89. package/dist/src/agents/simpleExample.js +0 -38
  90. package/dist/src/agents/system-review.d.ts +0 -5
  91. package/dist/src/agents/system-review.js +0 -181
  92. package/dist/src/agents/systemReview.d.ts +0 -4
  93. package/dist/src/agents/systemReview.js +0 -22
  94. package/dist/src/execute.d.ts +0 -49
  95. package/dist/src/execute.js +0 -564
  96. package/dist/src/princing.openai.js +0 -54
  97. package/dist/src/rag/tools.d.ts +0 -76
  98. package/dist/src/rag/tools.js +0 -196
  99. package/dist/src/rules/user.mapper.d.ts +0 -61
  100. package/dist/src/rules/user.mapper.js +0 -160
  101. package/dist/src/rules/utils/slug.d.ts +0 -22
  102. package/dist/src/rules/utils/slug.js +0 -35
@@ -321,7 +321,7 @@ async function gitLoadPR(git, branch) {
321
321
  if (!metadata) {
322
322
  throw new errors_1.GitOperationError(`PR not found for branch ${branch}`, 'pr_load', { branch });
323
323
  }
324
- const files = metadata.files || await (0, repo_tools_1.gitGetDiffFiles)(git, branch, metadata?.mergeBase, '.md');
324
+ const files = await (0, repo_tools_1.gitGetDiffFiles)(git, branch, metadata?.mergeBase, '.md');
325
325
  // Récupérer les infos du dernier commit de la branche
326
326
  const log = await git.log({ from: branch, to: branch, maxCount: 1 });
327
327
  const lastCommit = log.latest;
@@ -407,6 +407,21 @@ async function gitClosePRRobust(git, branch, closedBy, message, config) {
407
407
  if (!originalMetadata) {
408
408
  throw new errors_1.PRClosureError(`Could not find metadata on branch ${branch}. Cannot close.`, branch, 'metadata_not_found');
409
409
  }
410
+ // 2. Nettoyer tout état de merge en cours avant de commencer
411
+ try {
412
+ await git.raw(['merge', '--abort']).catch(() => {
413
+ // Ignorer si pas de merge en cours
414
+ });
415
+ // Reset de l'index au cas où il serait dans un état instable
416
+ await git.raw(['reset', '--merge']).catch(() => {
417
+ // Ignorer si pas nécessaire
418
+ });
419
+ }
420
+ catch (cleanupError) {
421
+ if (gitConf.verbose) {
422
+ console.warn('Cleanup before merge failed (non-critical):', cleanupError);
423
+ }
424
+ }
410
425
  // 3. Update the metadata note on the PR branch itself to mark it as closed
411
426
  const finalMetadata = {
412
427
  ...originalMetadata,
@@ -420,32 +435,106 @@ async function gitClosePRRobust(git, branch, closedBy, message, config) {
420
435
  await (0, repo_tools_1.gitWriteNote)(git, headCommitHash, finalMetadata, gitConf.gitNotes.namespace);
421
436
  // 4. Now, merge the updated PR branch into the target branch
422
437
  await git.checkout(originalMetadata.mergeBase || gitConf.draftBranch);
423
- const mergeResult = await git
424
- .env({
425
- GIT_AUTHOR_NAME: closedBy.name,
426
- GIT_AUTHOR_EMAIL: closedBy.email,
427
- GIT_COMMITTER_NAME: closedBy.name,
428
- GIT_COMMITTER_EMAIL: closedBy.email,
429
- })
430
- .merge([
431
- '--no-ff', '-X', 'theirs', '-m', `Merge branch '${branch}'`, branch
432
- ]);
438
+ // 5. Stratégie de merge robuste : FORCER la préservation des changements de la branche PR
439
+ // Note: "ours" dans ce contexte signifie "garder la version de la branche qu'on merge" (la PR)
440
+ // car nous sommes sur rule-editor et on merge la PR
441
+ let mergeResult;
442
+ try {
443
+ mergeResult = await git
444
+ .env({
445
+ GIT_AUTHOR_NAME: closedBy.name,
446
+ GIT_AUTHOR_EMAIL: closedBy.email,
447
+ GIT_COMMITTER_NAME: closedBy.name,
448
+ GIT_COMMITTER_EMAIL: closedBy.email,
449
+ })
450
+ .merge([
451
+ '--no-ff',
452
+ '--strategy', 'recursive',
453
+ '--strategy-option', 'theirs',
454
+ '-m', `Merge branch '${branch}'`,
455
+ branch
456
+ ]);
457
+ }
458
+ catch (mergeError) {
459
+ if (gitConf.verbose) {
460
+ console.error('Merge failed with recursive/theirs, trying ours strategy:', mergeError);
461
+ }
462
+ // Nettoyer le merge échoué
463
+ await git.raw(['merge', '--abort']).catch(() => { });
464
+ // Stratégie de fallback ultra-agressive: stratégie "ours" qui prend TOUJOURS la version de la branche source
465
+ // ATTENTION: Ici "ours" = la branche de destination (rule-editor), donc on inverse la logique
466
+ // Solution: utiliser --strategy-option theirs avec merge forcé
467
+ try {
468
+ // Récupérer les fichiers de la PR
469
+ const prFiles = originalMetadata.files || [];
470
+ // Merger avec stratégie ours d'abord (pour créer le commit de merge)
471
+ await git
472
+ .env({
473
+ GIT_AUTHOR_NAME: closedBy.name,
474
+ GIT_AUTHOR_EMAIL: closedBy.email,
475
+ GIT_COMMITTER_NAME: closedBy.name,
476
+ GIT_COMMITTER_EMAIL: closedBy.email,
477
+ })
478
+ .merge([
479
+ '--no-ff',
480
+ '--strategy', 'ours',
481
+ '-m', `Merge branch '${branch}'`,
482
+ branch
483
+ ]);
484
+ // Puis checkout des fichiers depuis la branche PR pour forcer leurs contenus
485
+ for (const file of prFiles) {
486
+ try {
487
+ await git.raw(['checkout', branch, '--', file]);
488
+ }
489
+ catch (fileError) {
490
+ if (gitConf.verbose) {
491
+ console.warn(`Could not checkout ${file} from ${branch}:`, fileError);
492
+ }
493
+ }
494
+ }
495
+ // Amend le commit de merge avec les bons contenus
496
+ await git.commit('--amend', ['--no-edit'], {
497
+ '--author': `${closedBy.name} <${closedBy.email}>`
498
+ });
499
+ mergeResult = { summary: { changes: prFiles.length } };
500
+ }
501
+ catch (fallbackError) {
502
+ throw new errors_1.PRClosureError(`Failed to merge PR ${branch} with all strategies: ${mergeError}\nFallback error: ${fallbackError}`, branch, 'merge_failed');
503
+ }
504
+ }
433
505
  const result = {
434
506
  metadata: finalMetadata,
435
507
  failed: false,
436
- conflicts: mergeResult.conflicts,
508
+ conflicts: mergeResult?.conflicts || [],
437
509
  raw: mergeResult,
438
510
  };
439
511
  return result;
440
512
  }
441
513
  catch (error) {
514
+ // Nettoyer l'état en cas d'erreur
515
+ try {
516
+ await git.raw(['merge', '--abort']).catch(() => { });
517
+ await git.raw(['reset', '--merge']).catch(() => { });
518
+ }
519
+ catch (cleanupError) {
520
+ if (gitConf.verbose) {
521
+ console.error('Failed to cleanup merge state:', cleanupError);
522
+ }
523
+ }
442
524
  if (error instanceof errors_1.PRClosureError)
443
525
  throw error;
444
526
  throw new errors_1.PRClosureError(`Failed to close PR ${branch}: ${error}`, branch, 'unknown');
445
527
  }
446
528
  finally {
447
529
  if (currentBranch) {
448
- await git.checkout(currentBranch);
530
+ try {
531
+ await git.checkout(currentBranch);
532
+ }
533
+ catch (checkoutError) {
534
+ if (gitConf.verbose) {
535
+ console.error(`Failed to checkout back to ${currentBranch}:`, checkoutError);
536
+ }
537
+ }
449
538
  }
450
539
  (0, repo_tools_1.unlock)('checkout');
451
540
  }
@@ -506,6 +595,21 @@ async function gitNewValidationRequest(git, files, description, author, options
506
595
  throw new errors_1.PRCreationError('Author is required', undefined, files);
507
596
  }
508
597
  try {
598
+ // ✅ CLEANUP: Nettoyer tout état de merge corrompu avant de créer la branche
599
+ // Cela évite l'erreur "you need to resolve your current index first"
600
+ try {
601
+ await git.raw(['merge', '--abort']).catch(() => {
602
+ // Ignorer si pas de merge en cours
603
+ });
604
+ await git.raw(['reset', '--merge']).catch(() => {
605
+ // Ignorer si pas nécessaire
606
+ });
607
+ }
608
+ catch (cleanupError) {
609
+ if (gitConfig.verbose) {
610
+ console.warn('Cleanup before branch creation failed (non-critical):', cleanupError);
611
+ }
612
+ }
509
613
  const nextID = await gitGetNextPRNumber(git, validationBranchPrefix);
510
614
  const newBranchName = `${validationBranchPrefix}${nextID}`;
511
615
  await git.checkoutBranch(newBranchName, sourceBranch);
@@ -2,11 +2,32 @@ import { SimpleGit } from 'simple-git';
2
2
  import { RulesGitConfig, PRMetadata, GitCommitHistory, GitFileSummary } from '../types';
3
3
  export declare function lock(key: string): Promise<void>;
4
4
  export declare function unlock(key: string): void;
5
+ /**
6
+ * Valide si une valeur est un entier valide pour un ID
7
+ *
8
+ * Un ID valide doit être:
9
+ * - Un nombre (type number)
10
+ * - Un entier (pas de décimales)
11
+ * - Supérieur à 999 (réservé pour les IDs système)
12
+ * - Fini (pas NaN, pas Infinity)
13
+ *
14
+ * @param id Valeur à valider
15
+ * @returns true si l'ID est valide, false sinon
16
+ *
17
+ * @example
18
+ * isValidInt(1234) // true
19
+ * isValidInt(999) // false (trop petit)
20
+ * isValidInt(1.5) // false (pas un entier)
21
+ * isValidInt(NaN) // false
22
+ * isValidInt("1234") // false (pas un nombre)
23
+ */
24
+ export declare function isValidInt(id: any): boolean;
5
25
  /**
6
26
  * Configuration et initialisation du client Git
27
+ * @param defaultConfig Configuration partielle optionnelle pour override
7
28
  * @returns Configuration Git avec l'instance et les chemins
8
29
  */
9
- export declare function gitLoad(defaultConfig?: RulesGitConfig): RulesGitConfig;
30
+ export declare function gitLoad(defaultConfig?: Partial<RulesGitConfig>): RulesGitConfig;
10
31
  /**
11
32
  * Récupère la prévisualisation d'un fichier depuis Git (opération bas niveau atomique),
12
33
  * sans les métadonnées.
@@ -35,6 +35,7 @@ var __importStar = (this && this.__importStar) || (function () {
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.lock = lock;
37
37
  exports.unlock = unlock;
38
+ exports.isValidInt = isValidInt;
38
39
  exports.gitLoad = gitLoad;
39
40
  exports.gitGetFilePreview = gitGetFilePreview;
40
41
  exports.gitGetFileContent = gitGetFileContent;
@@ -76,11 +77,50 @@ function unlock(key) {
76
77
  releasers.delete(key);
77
78
  }
78
79
  }
80
+ /**
81
+ * Valide si une valeur est un entier valide pour un ID
82
+ *
83
+ * Un ID valide doit être:
84
+ * - Un nombre (type number)
85
+ * - Un entier (pas de décimales)
86
+ * - Supérieur à 999 (réservé pour les IDs système)
87
+ * - Fini (pas NaN, pas Infinity)
88
+ *
89
+ * @param id Valeur à valider
90
+ * @returns true si l'ID est valide, false sinon
91
+ *
92
+ * @example
93
+ * isValidInt(1234) // true
94
+ * isValidInt(999) // false (trop petit)
95
+ * isValidInt(1.5) // false (pas un entier)
96
+ * isValidInt(NaN) // false
97
+ * isValidInt("1234") // false (pas un nombre)
98
+ */
99
+ function isValidInt(id) {
100
+ // Vérifier que c'est un nombre
101
+ if (typeof id !== 'number') {
102
+ return false;
103
+ }
104
+ // Vérifier que c'est un nombre fini (pas NaN, pas Infinity)
105
+ if (!Number.isFinite(id)) {
106
+ return false;
107
+ }
108
+ // Vérifier que c'est un entier
109
+ if (!Number.isInteger(id)) {
110
+ return false;
111
+ }
112
+ // Vérifier que c'est supérieur à 999
113
+ if (id <= 999) {
114
+ return false;
115
+ }
116
+ return true;
117
+ }
79
118
  // Global variables for git config and instance
80
119
  let gitConfig;
81
120
  let git;
82
121
  /**
83
122
  * Configuration et initialisation du client Git
123
+ * @param defaultConfig Configuration partielle optionnelle pour override
84
124
  * @returns Configuration Git avec l'instance et les chemins
85
125
  */
86
126
  function gitLoad(defaultConfig) {
@@ -99,6 +139,13 @@ function gitLoad(defaultConfig) {
99
139
  const validationToken = defaultConfig?.validationToken || process.env.DEFAULT_VALIDATION_TOKEN;
100
140
  const sshKeyPath = process.env.GIT_SSH_KEY_PATH;
101
141
  const sshPassphrase = process.env.GIT_SSH_PASSPHRASE;
142
+ // Configuration de la validation des IDs
143
+ const withID = defaultConfig?.withID !== undefined
144
+ ? defaultConfig.withID
145
+ : process.env.GIT_WITH_ID == 'true';
146
+ const strictID = defaultConfig?.strictID !== undefined
147
+ ? defaultConfig.strictID
148
+ : process.env.GIT_STRICT_ID == 'true';
102
149
  if (!repoPath || !draftBranch || !uploadPath || !mainBranch || !validationToken) {
103
150
  throw new errors_1.GitConfigurationError(messages_1.i18nRules.git_config_incomplete, 'repoPath|draftBranch|uploadPath|mainBranch|validationToken');
104
151
  }
@@ -152,7 +199,9 @@ function gitLoad(defaultConfig) {
152
199
  remoteUrl,
153
200
  verbose,
154
201
  canForce: defaultConfig?.canForce,
155
- reset: defaultConfig?.reset
202
+ reset: defaultConfig?.reset,
203
+ withID,
204
+ strictID
156
205
  };
157
206
  git = gitInstance;
158
207
  return gitConfig;
@@ -122,13 +122,10 @@ export interface FrontMatter {
122
122
  id?: number;
123
123
  /** Titre descriptif de la règle */
124
124
  title: string;
125
+ /** Ancien nom de fichier (pour renommage) */
125
126
  oldfile?: string;
126
- /** Liste des identifiants/alias pour cette règle (pour recherche) */
127
- slugs: string[];
128
- /** Version de la règle (optionnelle, format libre) */
129
- version?: string;
130
- /** Auteur original de la règle */
131
- author?: RuleUser;
127
+ /** Auteur original de la règle (format git: "Name <email>") */
128
+ author?: string;
132
129
  /** Email du validateur assigné à cette règle */
133
130
  validator?: string;
134
131
  /** Indique si la règle est finalisée et prête pour validation */
@@ -136,14 +133,8 @@ export interface FrontMatter {
136
133
  /** Service ou département propriétaire de cette règle */
137
134
  service?: string;
138
135
  /** Type de contenu de ce document */
139
- role?: "rule" | "template" | "rule-helper" | "web" | "document";
140
- /** Tags de catégorisation pour recherche et filtrage */
141
- tags?: string[];
142
- /** Date de dernière modification explicite */
143
- lastModified?: Date;
144
- /** Clé personnalisée pour données additionnelles */
145
- custom?: string;
146
- [key: string]: string | Date | number | string[] | RuleUser | boolean | undefined;
136
+ role?: "rule" | "template" | "rule-helper" | "web" | "document" | string;
137
+ [key: string]: string | Date | number | boolean | undefined;
147
138
  }
148
139
  /**
149
140
  * Représente un élément de l'historique Git d'une règle
@@ -282,6 +273,17 @@ export interface RulesGitConfig {
282
273
  remoteUrl?: string;
283
274
  /** Active les logs verbeux pour debug */
284
275
  verbose?: boolean;
276
+ /**
277
+ * Active la validation et génération automatique des IDs dans le matter
278
+ * @default false (pour compatibilité ascendante)
279
+ */
280
+ withID?: boolean;
281
+ /**
282
+ * Mode strict : rejeter les documents sans ID valide
283
+ * Nécessite withID: true
284
+ * @default false (génère l'ID si manquant)
285
+ */
286
+ strictID?: boolean;
285
287
  }
286
288
  /**
287
289
  * Configuration des options de concurrence pour les opérations Git
@@ -508,3 +510,14 @@ export interface GitHealthStatus {
508
510
  /** Recommandations de réparation */
509
511
  recommendations: string[];
510
512
  }
513
+ /**
514
+ * Rapport de migration des notes Git
515
+ */
516
+ export interface GitPrNoteMigrationReport {
517
+ migrated: number;
518
+ alreadyOk: number;
519
+ lost: Array<{
520
+ branch: string;
521
+ prNumber: number;
522
+ }>;
523
+ }
@@ -30,10 +30,6 @@ import { FrontMatter, Rule } from "./types";
30
30
  * ```
31
31
  */
32
32
  export declare function matterParse(markdown: string): {
33
- matter: {};
34
- content: string;
35
- data?: undefined;
36
- } | {
37
33
  data: any;
38
34
  content: string;
39
35
  matter: any;
@@ -38,7 +38,7 @@ function matterParse(markdown) {
38
38
  // 1. Séparer les lignes
39
39
  const lines = markdown.split(/\r?\n/);
40
40
  if (lines[0].trim() !== '---') {
41
- return { matter: {}, content: markdown }; // Pas de front-matter
41
+ return { matter: {}, content: markdown, data: {} }; // Pas de front-matter
42
42
  }
43
43
  // 2. Trouver la ligne de fermeture '---'
44
44
  let end = 1;
@@ -53,6 +53,17 @@ function matterParse(markdown) {
53
53
  const [rawKey, ...rawValue] = line.split(':');
54
54
  const key = rawKey.trim();
55
55
  const value = rawValue.join(':').trim();
56
+ // Détection de null explicite (YAML: null, ~) - ne pas créer la clé
57
+ if (value === 'null' || value === '~' || value === 'Null' || value === 'NULL') {
58
+ // Si la valeur est null, ne pas créer la clé (comme undefined)
59
+ continue;
60
+ }
61
+ // Si la valeur est vide (chaîne vide après trim), définir comme chaîne vide
62
+ // L'utilisateur peut définir un string vide pour indiquer qu'il n'a pas de valeur pour ce champ
63
+ if (!value) {
64
+ matter[key] = '';
65
+ continue;
66
+ }
56
67
  // Détection et parsing des arrays YAML
57
68
  if (value.startsWith('[') && value.endsWith(']')) {
58
69
  try {
@@ -86,10 +97,14 @@ function matterParse(markdown) {
86
97
  }
87
98
  // 4. parse slugs and tags as arrays
88
99
  // Ensure slugs is always an array
89
- // TODO: this code is not clean enough
100
+ // FIXME: this code is dead no more slugs in matter
90
101
  if (matter.slugs && typeof matter.slugs === 'string') {
91
102
  matter.slugs = matter.slugs.split(',').map((s) => s.trim()).filter((s) => s.length);
92
103
  }
104
+ // Ensure id is always a number
105
+ if (matter.id && typeof matter.id === 'string') {
106
+ matter.id = Number(matter.id);
107
+ }
93
108
  // Ensure tags is always an array
94
109
  if (matter.tags && typeof matter.tags === 'string') {
95
110
  const tagsStr = matter.tags;
@@ -115,21 +130,34 @@ function matterSerializeFromRule(rule) {
115
130
  function matterSerialize(content, matter) {
116
131
  // Créer un objet propre pour le front-matter (exclure oldfile)
117
132
  const cleanMatter = { ...matter };
118
- //
119
- // FIX: Convertir la Date en string pour éviter l'erreur YAML
120
- cleanMatter.lastModified = (cleanMatter.lastModified instanceof Date) ? `${new Date().toISOString()}` : `${cleanMatter.lastModified}`;
121
133
  const result = Object.keys(cleanMatter).reduce((acc, key) => {
122
134
  const value = cleanMatter[key];
135
+ // Ignorer les valeurs undefined, null ou chaînes vides
136
+ if (value === undefined || value === null || value === '') {
137
+ return acc;
138
+ }
123
139
  if (Array.isArray(value)) {
124
140
  return acc + `${key}: '${value.join(',')}'\n`;
125
141
  }
142
+ else if (typeof value === 'number') {
143
+ // ✅ FIX: Ne PAS mettre de guillemets autour des nombres
144
+ return acc + `${key}: ${value}\n`;
145
+ }
146
+ else if (typeof value === 'boolean') {
147
+ // ✅ FIX: Ne PAS mettre de guillemets autour des booléens
148
+ return acc + `${key}: ${value}\n`;
149
+ }
150
+ else if (value instanceof Date) {
151
+ // ✅ FIX: Convertir Date en ISO string avec guillemets
152
+ return acc + `${key}: '${value.toISOString()}'\n`;
153
+ }
126
154
  else {
155
+ // Pour les strings, mettre des guillemets
127
156
  return acc + `${key}: '${value}'\n`;
128
157
  }
129
158
  }, '');
130
159
  return `---
131
- ${result}
132
- ---
160
+ ${result}---
133
161
  ${content}`;
134
162
  }
135
163
  /**
@@ -1,3 +1,4 @@
1
+ import { FrontMatter } from "./rules/types";
1
2
  export declare function extractCaptcha(base64Image: string, openai: any): Promise<{
2
3
  number: any;
3
4
  cost: number;
@@ -7,49 +8,41 @@ export declare function extractCaptcha(base64Image: string, openai: any): Promis
7
8
  *
8
9
  * @param {string} inputfile - The name of the PDF file being processed
9
10
  * @param {any} pdfData - The extracted content from the PDF file
10
- * @param {any} openai - The OpenAI client instance
11
11
  * @param {any[]} links - Optional array of links extracted from the PDF to be integrated into the markdown
12
+ * @param {string} model - The model to use for parsing (default: "MEDIUM-fast")
12
13
  * @returns {Promise<{markdown: string, cost: number}>} - The parsed markdown content and the cost of the API call
13
14
  */
14
- export declare function callGPTForParsingPDF(inputfile: string, pdfData: any, openai: any, links?: any[]): Promise<{
15
- markdown: any;
15
+ export declare function callLLMForParsingPDF(inputfile: string, pdfData: any, links?: any[], model?: string): Promise<{
16
+ markdown: string;
16
17
  cost: number;
17
18
  }>;
18
- /**
19
- * Convertit un document HTML en markdown en appelant le modèle GPT (ex: gpt-4.1)
20
- * pour analyser et reformater le document.
21
- *
22
- * @param {any} htmlData - Le document HTML à transformer en markdown.
23
- * @param {any} openai - L'instance OpenAI configurée pour appeler l'API.
24
- * @param {boolean} simple - Si true, utilise un prompt simplifié.
25
- * @returns {Promise<Object>} - Le contenu markdown structuré créé par le modèle LLM.
26
- */
27
- export declare function callGPTForParsingHTML(html: string, openai: any): Promise<any>;
28
19
  /**
29
20
  * Parses an HTML file and converts it to markdown using GPT.
30
21
  *
31
22
  * @param {string} output - The directory path where the output markdown file will be saved.
32
23
  * @param {string} file - The path to the HTML file to be parsed.
33
24
  * @param {string} service - The service name used as part of the output filename output.
34
- * @param {any} openai - The OpenAI instance to use for the GPT API calls.
25
+ * @param {string} model - The model to use for parsing (default: "MEDIUM-fast")
35
26
  * @returns {Promise<{markdown: string, cost: number}>} - The generated markdown content and the cost of the GPT API call.
36
27
  */
37
- export declare function html2markdown(output: string, file: string, service: string, openai: any): Promise<{
38
- markdown: any;
28
+ export declare function html2markdown(output: string, file: string, service: string, model?: string): Promise<{
29
+ markdown: string;
39
30
  cost: number;
40
31
  }>;
41
32
  /**
42
33
  * Parse un PDF en effectuant :
43
34
  * 1. Le nettoyage du PDF avec Ghostscript.
44
35
  * 2. Sa conversion en XML via pdftohtml.
45
- * 3. (Optionnellement) Le passage du contenu converti au modèle GPT pour analyser la structure.
36
+ * 3. (Optionnellement) Le passage du contenu converti au modèle LLM pour analyser la structure.
46
37
  *
47
- * @param {string} file - Chemin vers le fichier PDF à analyser.
48
- * @param {any} openai - L'instance configurée pour appeler l'API OpenAI.
49
- * @returns {Promise<any>} - Le markdown structuré (issue de GPT) ou tout autre traitement souhaité.
38
+ * @param {string} outputDir - Dossier de sortie pour le fichier markdown.
39
+ * @param {string} pdf - Chemin vers le fichier PDF à analyser.
40
+ * @param {FrontMatter|null} matter - Métadonnées du document (title, service, author, role). Si null, utilise le nom du PDF pour le titre.
41
+ * @param {string} model - Le modèle à utiliser (défaut: "MEDIUM-fast").
42
+ * @returns {Promise<{markdown: string, cost: number, outputPath: string}>} - Le markdown structuré, le coût et le chemin du fichier de sortie.
50
43
  */
51
- export declare function pdf2markdown(folder: string, file: string, service: string, openai: any): Promise<{
52
- markdown: any;
44
+ export declare function pdf2markdown(outputDir: string, pdf: string, matter: FrontMatter | null, model?: string): Promise<{
45
+ markdown: string;
53
46
  cost: number;
54
47
  outputPath: string;
55
48
  }>;