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
@@ -59,6 +59,8 @@ const errors_1 = require("../errors");
59
59
  const path_1 = require("path");
60
60
  const fs = __importStar(require("fs/promises"));
61
61
  const repo_tools_1 = require("./repo.tools");
62
+ const repo_pr_1 = require("./repo.pr");
63
+ const utils_matter_1 = require("../utils.matter");
62
64
  /**
63
65
  * Service singleton pour gérer le registre d'IDs en mémoire
64
66
  */
@@ -561,7 +563,7 @@ function gitEnsureMatterID(matter, config, branch, file) {
561
563
  // (Si même fichier, registerExistingID ne lève pas d'erreur)
562
564
  }
563
565
  }
564
- // Générer un nouvel ID
566
+ // Générer un nouvel ID (si aucun ID fourni ou ID invalide)
565
567
  matter.id = gitGenerateNextID(config);
566
568
  // FIXME: Double save ici - gitGenerateNextID() fait save() puis gitRegisterExistingID() fait save() aussi
567
569
  // Refactorisation future: Retirer save() de gitGenerateNextID() et le faire uniquement dans gitRegisterExistingID()
@@ -999,13 +1001,20 @@ async function gitCheckConfiguration(git) {
999
1001
  return check;
1000
1002
  }
1001
1003
  /**
1002
- * Crée un fichier dans la branche draft (opération bas niveau)
1003
- * @param git Instance Git
1004
+ * Crée ou modifie un fichier dans une branche Git et fait un commit automatique
1005
+ *
1006
+ * @param git Instance SimpleGit
1004
1007
  * @param filePath Chemin du fichier
1005
1008
  * @param PR Nom de la branche de Pull Request
1006
1009
  * @param content Contenu du fichier
1007
- * @param user Utilisateur qui effectue l'opération
1008
- * @param config Configuration Git (optionnel, utilise la config globale)
1010
+ * @param user Utilisateur qui fait le commit
1011
+ * @param config Configuration Git optionnelle
1012
+ * @returns Historique du commit créé
1013
+ *
1014
+ * @fixme Ajouter un paramètre optionnel `commitMessage?: string` pour permettre de personnaliser
1015
+ * le message de commit au lieu d'utiliser toujours `commit: ${filePath}` par défaut.
1016
+ * Cela permettrait aux callers de spécifier des messages plus descriptifs.
1017
+ *
1009
1018
  * @throws GitOperationError si la création échoue
1010
1019
  */
1011
1020
  async function gitCreateOrEditFile(git, filePath, PR, content, user, config) {
@@ -1019,8 +1028,7 @@ async function gitCreateOrEditFile(git, filePath, PR, content, user, config) {
1019
1028
  if (gitConf.withID) {
1020
1029
  try {
1021
1030
  // Import dynamique pour éviter les dépendances circulaires
1022
- const { matterParse, matterSerialize } = await Promise.resolve().then(() => __importStar(require('../utils.matter')));
1023
- const parsed = matterParse(content);
1031
+ const parsed = (0, utils_matter_1.matterParse)(content);
1024
1032
  if (gitConf.strictID) {
1025
1033
  // Mode strict : valider que l'ID existe et est correct
1026
1034
  validateMatter(parsed.matter);
@@ -1040,7 +1048,7 @@ async function gitCreateOrEditFile(git, filePath, PR, content, user, config) {
1040
1048
  // Seulement si l'ID est manquant ou invalide
1041
1049
  parsed.matter = gitEnsureMatterID(parsed.matter, gitConf, PR, filePath);
1042
1050
  // Re-sérialiser avec l'ID mis à jour
1043
- content = matterSerialize(parsed.content, parsed.matter);
1051
+ content = (0, utils_matter_1.matterSerialize)(parsed.content, parsed.matter);
1044
1052
  }
1045
1053
  else {
1046
1054
  // ✅ L'ID existe déjà : gitRegisterExistingID() appelle maintenant setMatterCache() automatiquement
@@ -1052,7 +1060,7 @@ async function gitCreateOrEditFile(git, filePath, PR, content, user, config) {
1052
1060
  if (error.code === 'id_already_used') {
1053
1061
  // En mode non-strict, générer un nouvel ID si doublon détecté
1054
1062
  parsed.matter = gitEnsureMatterID(parsed.matter, gitConf, PR, filePath);
1055
- content = matterSerialize(parsed.content, parsed.matter);
1063
+ content = (0, utils_matter_1.matterSerialize)(parsed.content, parsed.matter);
1056
1064
  // ✅ Ne pas propager l'erreur, continuer avec le nouvel ID généré
1057
1065
  }
1058
1066
  else {
@@ -1089,13 +1097,15 @@ async function gitCreateOrEditFile(git, filePath, PR, content, user, config) {
1089
1097
  //
1090
1098
  // without note the branche is not a valid PR branch
1091
1099
  const oldNote = await (0, repo_tools_1.gitReadNote)(git, PR, gitConf.gitNotes.namespace, 10);
1100
+ if (oldNote && gitConf.verbose) {
1101
+ console.debug('[gitCreateOrEditFile] metadata.files before update:', oldNote.files);
1102
+ }
1092
1103
  const commit = await _writeFileAndCommit(git, filePath, content, user, gitConf, `commit: ${filePath}`);
1093
1104
  // ✅ Mettre à jour le cache du matter après sauvegarde
1094
1105
  // NOTE: Le cache est TOUJOURS mis à jour, indépendamment de withID
1095
1106
  // C'est une opération de cache, pas une validation
1096
1107
  try {
1097
- const { matterParse } = await Promise.resolve().then(() => __importStar(require('../utils.matter')));
1098
- const parsed = matterParse(content);
1108
+ const parsed = (0, utils_matter_1.matterParse)(content);
1099
1109
  idRegistryService.init(gitConf.repoPath);
1100
1110
  idRegistryService.setMatterCache(PR, filePath, {
1101
1111
  id: parsed.matter.id,
@@ -1124,11 +1134,15 @@ async function gitCreateOrEditFile(git, filePath, PR, content, user, config) {
1124
1134
  }
1125
1135
  // Determine the current head after the commit attempt.
1126
1136
  const newHead = (await git.revparse(['HEAD'])).trim();
1127
- const newFiles = await (0, repo_tools_1.gitGetDiffFiles)(git, PR, oldNote.mergeBase);
1137
+ let newFiles = await (0, repo_tools_1.gitGetDiffFiles)(git, PR, oldNote.mergeBase);
1138
+ newFiles = await sanitizePRFiles(git, newFiles, PR);
1128
1139
  const updatedNote = {
1129
1140
  ...oldNote,
1130
1141
  files: newFiles,
1131
1142
  };
1143
+ if (gitConf.verbose) {
1144
+ console.debug('[gitCreateOrEditFile] metadata.files after update:', updatedNote.files);
1145
+ }
1132
1146
  // Write the note to the current HEAD of the PR branch.
1133
1147
  // If no commit was made, this overwrites the note on oldHead.
1134
1148
  // If a new commit was made, this writes the note on newHead.
@@ -1331,12 +1345,24 @@ async function gitRenameFile(git, oldFileName, newFileName, branch, user, config
1331
1345
  //
1332
1346
  //FIXME: add a check about the branch (file can be NEW and on branch)
1333
1347
  const fullOldPath = (0, path_1.join)(gitConf.uploadPath, oldFileName);
1348
+ let result;
1334
1349
  if ((0, fs_1.existsSync)(fullOldPath)) {
1335
- return await gitRenameFile_fs(git, oldFileName, newFileName, branch, user, config);
1350
+ result = await gitRenameFile_fs(git, oldFileName, newFileName, branch, user, config);
1336
1351
  }
1337
1352
  else {
1338
- return await gitRenameFile_git(git, oldFileName, newFileName, branch, user, config);
1353
+ result = await gitRenameFile_git(git, oldFileName, newFileName, branch, user, config);
1354
+ if (branch !== 'NEW' && branch.startsWith(gitConf.validationPrefix)) {
1355
+ try {
1356
+ await (0, repo_pr_1.gitPRReplaceFile)(git, branch, { remove: oldFileName, add: newFileName }, gitConf);
1357
+ }
1358
+ catch (metadataError) {
1359
+ if (gitConf.verbose) {
1360
+ console.warn('⚠️ Failed to update PR metadata after rename:', metadataError);
1361
+ }
1362
+ }
1363
+ }
1339
1364
  }
1365
+ return result;
1340
1366
  }
1341
1367
  catch (error) {
1342
1368
  // Pour les vraies branches Git, ne pas faire de fallback filesystem
@@ -1663,9 +1689,7 @@ function createUnhealthyStatus(branch, exists, accessible, clean, mergeInProgres
1663
1689
  * Vérifie si un merge est en cours en regardant les fichiers Git
1664
1690
  */
1665
1691
  async function checkMergeInProgress(repoPath) {
1666
- const { existsSync } = await Promise.resolve().then(() => __importStar(require('fs')));
1667
- const { join } = await Promise.resolve().then(() => __importStar(require('path')));
1668
- const gitDir = join(repoPath, '.git');
1692
+ const gitDir = (0, path_1.join)(repoPath, '.git');
1669
1693
  const mergeFiles = [
1670
1694
  'MERGE_HEAD',
1671
1695
  'MERGE_MODE',
@@ -1673,5 +1697,27 @@ async function checkMergeInProgress(repoPath) {
1673
1697
  'CHERRY_PICK_HEAD',
1674
1698
  'REVERT_HEAD'
1675
1699
  ];
1676
- return mergeFiles.some(file => existsSync(join(gitDir, file)));
1700
+ return mergeFiles.some(file => (0, fs_1.existsSync)((0, path_1.join)(gitDir, file)));
1701
+ }
1702
+ async function sanitizePRFiles(git, files, branch) {
1703
+ if (!files || files.length === 0) {
1704
+ return [];
1705
+ }
1706
+ const checks = await Promise.all(files.map(async (file) => ({
1707
+ file,
1708
+ exists: await (0, repo_tools_1.gitFileExistsInBranch)(git, file, branch)
1709
+ })));
1710
+ const sanitized = [];
1711
+ const seen = new Set();
1712
+ for (const { file, exists } of checks) {
1713
+ if (!exists) {
1714
+ continue;
1715
+ }
1716
+ if (seen.has(file)) {
1717
+ continue;
1718
+ }
1719
+ seen.add(file);
1720
+ sanitized.push(file);
1721
+ }
1722
+ return sanitized;
1677
1723
  }
@@ -79,6 +79,14 @@ export declare function gitGetAllPR(git: SimpleGit, options?: {
79
79
  */
80
80
  export declare function gitGetClosedPRs(git: SimpleGit, gitConfig: RulesGitConfig): Promise<PRInfo[]>;
81
81
  export declare function gitLoadPR(git: SimpleGit, branch: string): Promise<PRInfo>;
82
+ /**
83
+ * Remplace explicitement un nom de fichier dans les métadonnées d'une PR.
84
+ * Utilisé pour refléter immédiatement les renames sans dépendre de git diff.
85
+ */
86
+ export declare function gitPRReplaceFile(git: SimpleGit, branch: string, options?: {
87
+ remove?: string;
88
+ add?: string;
89
+ }, config?: RulesGitConfig): Promise<void>;
82
90
  export declare function gitPRUpdateComments(git: SimpleGit, branch: string, details: RulePullRequestDetails, config?: RulesGitConfig): Promise<PRInfo>;
83
91
  /**
84
92
  * DEPRECATED: use gitClosePRRobust instead
@@ -40,6 +40,7 @@ exports.gitGetPRMetadata = gitGetPRMetadata;
40
40
  exports.gitGetAllPR = gitGetAllPR;
41
41
  exports.gitGetClosedPRs = gitGetClosedPRs;
42
42
  exports.gitLoadPR = gitLoadPR;
43
+ exports.gitPRReplaceFile = gitPRReplaceFile;
43
44
  exports.gitPRUpdateComments = gitPRUpdateComments;
44
45
  exports.gitClosePR = gitClosePR;
45
46
  exports.gitClosePRRobust = gitClosePRRobust;
@@ -321,7 +322,7 @@ async function gitLoadPR(git, branch) {
321
322
  if (!metadata) {
322
323
  throw new errors_1.GitOperationError(`PR not found for branch ${branch}`, 'pr_load', { branch });
323
324
  }
324
- const files = await (0, repo_tools_1.gitGetDiffFiles)(git, branch, metadata?.mergeBase, '.md');
325
+ const files = metadata.files || (await (0, repo_tools_1.gitGetDiffFiles)(git, branch, metadata?.mergeBase, '.md'));
325
326
  // Récupérer les infos du dernier commit de la branche
326
327
  const log = await git.log({ from: branch, to: branch, maxCount: 1 });
327
328
  const lastCommit = log.latest;
@@ -341,6 +342,49 @@ async function gitLoadPR(git, branch) {
341
342
  throw new errors_1.GitOperationError(`Failed to retrieve PR: ${error}`, 'pr_load');
342
343
  }
343
344
  }
345
+ /**
346
+ * Remplace explicitement un nom de fichier dans les métadonnées d'une PR.
347
+ * Utilisé pour refléter immédiatement les renames sans dépendre de git diff.
348
+ */
349
+ async function gitPRReplaceFile(git, branch, options = {}, config) {
350
+ const { remove, add } = options;
351
+ if (!remove && !add) {
352
+ return;
353
+ }
354
+ const gitConf = (0, repo_tools_1.gitLoad)(config);
355
+ const metadata = await gitGetPRMetadata(git, branch, config);
356
+ if (!metadata) {
357
+ return;
358
+ }
359
+ const currentFiles = Array.isArray(metadata.files) ? metadata.files : [];
360
+ const seen = new Set();
361
+ const nextFiles = [];
362
+ for (const file of currentFiles) {
363
+ if (!file) {
364
+ continue;
365
+ }
366
+ if (remove && file === remove) {
367
+ continue;
368
+ }
369
+ if (seen.has(file)) {
370
+ continue;
371
+ }
372
+ seen.add(file);
373
+ nextFiles.push(file);
374
+ }
375
+ if (add && !seen.has(add)) {
376
+ nextFiles.push(add);
377
+ seen.add(add);
378
+ }
379
+ const changed = currentFiles.length !== nextFiles.length ||
380
+ currentFiles.some((file, idx) => file !== nextFiles[idx]);
381
+ if (!changed) {
382
+ return;
383
+ }
384
+ metadata.files = nextFiles;
385
+ const headCommitHash = (await git.revparse([branch])).trim();
386
+ await (0, repo_tools_1.gitWriteNote)(git, headCommitHash, metadata, gitConf.gitNotes.namespace);
387
+ }
344
388
  async function gitPRUpdateComments(git, branch, details, config) {
345
389
  const gitConf = (0, repo_tools_1.gitLoad)(config);
346
390
  const metadata = await gitGetPRMetadata(git, branch, config);
@@ -56,7 +56,11 @@ export declare function gitReadFileOutsideRepo(git: SimpleGit, filePath: string)
56
56
  content: string;
57
57
  date: Date;
58
58
  }>;
59
- export declare function gitGetFileHistory(git: SimpleGit, filename: string, hash?: string): Promise<GitCommitHistory[]>;
59
+ export declare function gitGetFileHistory(git: SimpleGit, filename: string, options?: {
60
+ hash?: string;
61
+ branch?: string;
62
+ maxCommits?: number;
63
+ }): Promise<GitCommitHistory[]>;
60
64
  /**
61
65
  * Récupère le dernier commit d'une branche (opération bas niveau atomique)
62
66
  * @param git Instance SimpleGit
@@ -338,10 +338,23 @@ async function gitReadFileOutsideRepo(git, filePath) {
338
338
  throw error;
339
339
  }
340
340
  }
341
- async function gitGetFileHistory(git, filename, hash) {
341
+ async function gitGetFileHistory(git, filename, options) {
342
+ // - Normalisation des paramètres pour compatibilité
342
343
  try {
343
- const log = await git.log({ file: filename });
344
- const all = log.all.map(commit => ({
344
+ // - Utiliser git.log() pour obtenir l'historique des commits
345
+ // - git.log() retourne déjà les commits du plus récent au plus ancien (ordre standard Git)
346
+ const branch = options?.branch || 'HEAD';
347
+ const logArgs = [];
348
+ if (branch !== 'HEAD') {
349
+ logArgs.push(branch);
350
+ }
351
+ logArgs.push('--', filename);
352
+ const log = await git.log(logArgs);
353
+ if (log.all.length === 0) {
354
+ return [];
355
+ }
356
+ // - Construire l'historique (déjà dans l'ordre du plus récent au plus ancien)
357
+ let all = log.all.map(commit => ({
345
358
  hash: commit.hash,
346
359
  date: new Date(commit.date),
347
360
  message: commit.message,
@@ -350,10 +363,44 @@ async function gitGetFileHistory(git, filename, hash) {
350
363
  email: commit.author_email
351
364
  }
352
365
  }));
353
- // Si un hash est fourni, retourner le contenu du fichier à ce hash
354
- if (hash) {
355
- const fileContent = await gitGetFileContent(git, filename, hash);
356
- const index = all.findIndex(commit => commit.hash === hash);
366
+ // - Si un hash est fourni, s'assurer qu'il est inclus avant l'échantillonnage
367
+ let requestedHashIndex = -1;
368
+ if (options?.hash) {
369
+ requestedHashIndex = all.findIndex(commit => commit.hash === options.hash);
370
+ }
371
+ // - Limitation du nombre de commits avec échantillonnage uniforme
372
+ // - Garantit que le premier (plus récent) et dernier (plus ancien) commit sont inclus
373
+ // - Si un hash spécifique est demandé, il est aussi garanti d'être inclus
374
+ if (options?.maxCommits && all.length > options.maxCommits) {
375
+ const step = Math.ceil((all.length - 2) / (options.maxCommits - 2)) || 1;
376
+ const sampled = [all[0]]; // Premier commit (plus récent)
377
+ const includedIndices = new Set([0]); // Track des indices déjà inclus
378
+ // - Si un hash spécifique est demandé et n'est pas le premier, l'ajouter
379
+ if (requestedHashIndex > 0 && requestedHashIndex < all.length - 1) {
380
+ sampled.push(all[requestedHashIndex]);
381
+ includedIndices.add(requestedHashIndex);
382
+ }
383
+ // - Échantillonnage des commits intermédiaires
384
+ for (let i = 1; i < all.length - 1; i += step) {
385
+ if (!includedIndices.has(i)) {
386
+ sampled.push(all[i]);
387
+ includedIndices.add(i);
388
+ }
389
+ if (sampled.length >= options.maxCommits - 1)
390
+ break;
391
+ }
392
+ // - Dernier commit (plus ancien) si on a encore de la place
393
+ if (sampled.length < options.maxCommits && all.length > 1 && !includedIndices.has(all.length - 1)) {
394
+ sampled.push(all[all.length - 1]);
395
+ }
396
+ // - Trier par date décroissante pour maintenir l'ordre (plus récent en premier)
397
+ sampled.sort((a, b) => b.date.getTime() - a.date.getTime());
398
+ all = sampled;
399
+ }
400
+ // - Si un hash est fourni, retourner le contenu du fichier à ce hash
401
+ if (options?.hash) {
402
+ const fileContent = await gitGetFileContent(git, filename, options.hash);
403
+ const index = all.findIndex(commit => commit.hash === options.hash);
357
404
  if (index !== -1 && fileContent) {
358
405
  all[index] = fileContent;
359
406
  }
@@ -334,6 +334,20 @@ export interface GitCommitHistory {
334
334
  /** Branche où s'est produit ce commit (optionnel) */
335
335
  branch?: string;
336
336
  }
337
+ /**
338
+ * Structure simplifiée d'un commit pour la prévisualisation
339
+ *
340
+ * Utilisée dans loadPreview() pour retourner uniquement les informations essentielles
341
+ * sans le contenu complet du commit.
342
+ */
343
+ export interface CommitPreview {
344
+ /** Hash unique du commit */
345
+ hash: string;
346
+ /** Date et heure du commit */
347
+ date: Date;
348
+ /** Nom de l'auteur du commit */
349
+ author: string;
350
+ }
337
351
  /**
338
352
  * Résumé d'un fichier Git avec son commit associé
339
353
  *
@@ -40,23 +40,3 @@ export declare function matterParse(markdown: string): {
40
40
  */
41
41
  export declare function matterSerializeFromRule(rule: Rule): string;
42
42
  export declare function matterSerialize(content: string, matter: FrontMatter | any): string;
43
- /**
44
- * Extrait le front-matter (entre les deux premiers '---') et le contenu Markdown.
45
- * Fonction 100% vanilla : aucun paquet externe requis.
46
- * PROS:
47
- * Code plus propre et maintenable
48
- * - Typage TypeScript strict
49
- * - Plus robuste (ignore lignes indentées)
50
- * - Séparation des responsabilités
51
- * - Meilleure architecture (parsing pur)
52
- * CONS:
53
- * - Perte de fonctionnalité (slugs/tags)
54
- *
55
- * @param markdown Texte Markdown brut
56
- * @returns Objet avec matter, content et data
57
- */
58
- export declare function matterParse_OTHER(markdown: string): {
59
- matter: Record<string, any>;
60
- content: string;
61
- data: Record<string, any>;
62
- };
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.matterParse = matterParse;
4
4
  exports.matterSerializeFromRule = matterSerializeFromRule;
5
5
  exports.matterSerialize = matterSerialize;
6
- exports.matterParse_OTHER = matterParse_OTHER;
7
6
  /**
8
7
  * Parse le front-matter YAML et le contenu Markdown d'un document
9
8
  *
@@ -152,85 +151,54 @@ function matterSerialize(content, matter) {
152
151
  return acc + `${key}: '${value.toISOString()}'\n`;
153
152
  }
154
153
  else {
155
- // Pour les strings, mettre des guillemets
156
- return acc + `${key}: '${value}'\n`;
154
+ const formatted = formatYAMLString(value.toString());
155
+ return acc + `${key}: ${formatted}\n`;
157
156
  }
158
157
  }, '');
159
158
  return `---
160
159
  ${result}---
161
160
  ${content}`;
162
161
  }
163
- /**
164
- * Extrait le front-matter (entre les deux premiers '---') et le contenu Markdown.
165
- * Fonction 100% vanilla : aucun paquet externe requis.
166
- * PROS:
167
- * Code plus propre et maintenable
168
- * - Typage TypeScript strict
169
- * - Plus robuste (ignore lignes indentées)
170
- * - Séparation des responsabilités
171
- * - Meilleure architecture (parsing pur)
172
- * CONS:
173
- * - Perte de fonctionnalité (slugs/tags)
174
- *
175
- * @param markdown Texte Markdown brut
176
- * @returns Objet avec matter, content et data
177
- */
178
- function matterParse_OTHER(markdown) {
179
- // 1. Séparer les lignes
180
- const lines = markdown.split(/\r?\n/);
181
- if (lines[0].trim() !== '---') {
182
- return { matter: {}, content: markdown, data: {} }; // Pas de front-matter
162
+ function formatYAMLString(value) {
163
+ const shouldQuote = needsQuotes(value);
164
+ if (!shouldQuote) {
165
+ return value;
183
166
  }
184
- // 2. Trouver la ligne de fermeture '---'
185
- let end = 1;
186
- while (end < lines.length && lines[end].trim() !== '---')
187
- end++;
188
- // 3. Parser le bloc front-matter (simple clé-valeur)
189
- const matter = {};
190
- for (let i = 1; i < end; i++) {
191
- const line = lines[i];
192
- if (!line.trim())
193
- continue; // ignorer les lignes vides
194
- // Ignorer les lignes indentées (structures complexes non supportées)
195
- if (line.startsWith(' ') || line.startsWith('\t')) {
196
- continue;
197
- }
198
- const trimmedLine = line.trim();
199
- if (trimmedLine.includes(':')) {
200
- const [rawKey, ...rawValue] = trimmedLine.split(':');
201
- const key = rawKey.trim();
202
- const value = rawValue.join(':').trim();
203
- if (value) {
204
- // Détection et parsing des arrays YAML
205
- if (value.startsWith('[') && value.endsWith(']')) {
206
- try {
207
- const parsed = JSON.parse(value);
208
- if (Array.isArray(parsed)) {
209
- matter[key] = parsed;
210
- }
211
- else {
212
- matter[key] = value.replace(/^["']|["']$/g, '');
213
- }
214
- }
215
- catch (e) {
216
- matter[key] = value.replace(/^["']|["']$/g, '');
217
- }
218
- }
219
- // Tentative de typage léger : nombre, booléen, sinon chaîne
220
- else if (/^(true|false)$/i.test(value)) {
221
- matter[key] = value.toLowerCase() === 'true';
222
- }
223
- else if (!isNaN(Number(value)) && value !== '') {
224
- matter[key] = Number(value);
225
- }
226
- else {
227
- matter[key] = value.replace(/^["']|["']$/g, '');
228
- }
229
- }
230
- }
167
+ if (process.env.DEBUG_YAML === '1') {
168
+ console.warn('[matterSerialize] quoting value:', value);
231
169
  }
232
- // 4. Restituer le contenu Markdown sans le front-matter
233
- const content = lines.slice(end + 1).join('\n').trimStart();
234
- const data = matter;
235
- return { data, content, matter };
170
+ const escaped = value.replace(/'/g, "''");
171
+ return `'${escaped}'`;
172
+ }
173
+ function needsQuotes(value) {
174
+ if (value.length === 0) {
175
+ return true;
176
+ }
177
+ const firstChar = value[0];
178
+ const lastChar = value[value.length - 1];
179
+ if (firstChar === ' ' || lastChar === ' ') {
180
+ return true;
181
+ }
182
+ if (/[:#{}\[\],&*?]/.test(value)) {
183
+ return true;
184
+ }
185
+ if (/^-/.test(value)) {
186
+ return true;
187
+ }
188
+ if (/^\d/.test(value)) {
189
+ return true;
190
+ }
191
+ if (value.includes('\n')) {
192
+ return true;
193
+ }
194
+ if (value.includes('- ')) {
195
+ return true;
196
+ }
197
+ if (value.includes('"')) {
198
+ return true;
199
+ }
200
+ if (value.includes("'")) {
201
+ return true;
202
+ }
203
+ return false;
236
204
  }
@@ -13,7 +13,7 @@ const path_1 = __importDefault(require("path"));
13
13
  const fs_1 = __importDefault(require("fs"));
14
14
  const jsdom_1 = require("jsdom");
15
15
  const readability_1 = require("@mozilla/readability");
16
- const pricing_llm_1 = require("./pricing.llm");
16
+ const pricing_1 = require("./llm/pricing");
17
17
  const prompts_1 = require("./prompts");
18
18
  const utils_1 = require("./utils");
19
19
  const execute_1 = require("./execute");
@@ -37,7 +37,7 @@ async function extractCaptcha(base64Image, openai) {
37
37
  messages: [{ role: "user", content }],
38
38
  max_completion_tokens: 50,
39
39
  });
40
- const cost = (0, pricing_llm_1.calculateCost)(model, response.usage);
40
+ const cost = (0, pricing_1.calculateCost)(model, response.usage);
41
41
  // Récupérer la réponse markdown
42
42
  const number = response.choices[0].message.content;
43
43
  return { number, cost };
@@ -1,13 +1,5 @@
1
1
  import { ParsedFunctionToolCall } from "openai/resources/beta/chat/completions";
2
2
  import { AgentConfig, AgenticContext } from "./types";
3
- import OpenAI from "openai";
4
- /**
5
- * global openai instance
6
- */
7
- declare global {
8
- var _openaiInstance_: OpenAI | undefined;
9
- }
10
- export declare const openaiInstance: (envKey?: string, baseUrl?: string) => OpenAI;
11
3
  /**
12
4
  * Converts a string to a URL-friendly slug
13
5
  * @param text The text to convert to a slug
package/dist/src/utils.js CHANGED
@@ -1,36 +1,9 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.toSlug = exports.openaiInstance = void 0;
3
+ exports.toSlug = void 0;
7
4
  exports.injectTransferTools = injectTransferTools;
8
5
  exports.handleTransferCall = handleTransferCall;
9
6
  const prompts_1 = require("./prompts");
10
- const openai_1 = __importDefault(require("openai"));
11
- const openaiInstance = function (envKey, baseUrl) {
12
- if (globalThis._openaiInstance_) {
13
- return globalThis._openaiInstance_;
14
- }
15
- if (!envKey) {
16
- throw new Error('AI API key is missing');
17
- }
18
- //
19
- // use multiple fallback if envKey is not set
20
- const options = {
21
- apiKey: process.env[envKey] || envKey || process.env.API_LLM_KEY || process.env.OPENAI_API_KEY,
22
- timeout: 60000 * 15
23
- };
24
- if (baseUrl) {
25
- options.baseURL = baseUrl;
26
- }
27
- globalThis._openaiInstance_ = new openai_1.default(options);
28
- if (!globalThis._openaiInstance_) {
29
- throw new Error('OpenAI instance has not been initialized');
30
- }
31
- return globalThis._openaiInstance_;
32
- };
33
- exports.openaiInstance = openaiInstance;
34
7
  /**
35
8
  * Converts a string to a URL-friendly slug
36
9
  * @param text The text to convert to a slug
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentic-api",
3
- "version": "2.0.491",
3
+ "version": "2.0.592",
4
4
  "description": "API pour l'orchestration d'agents intelligents avec séquences et escalades automatiques",
5
5
  "main": "dist/src/index.js",
6
6
  "types": "dist/src/index.d.ts",