agentic-api 2.0.31 → 2.0.314

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 (89) 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 +42 -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 +4 -0
  12. package/dist/src/agents/simulator.executor.d.ts +5 -1
  13. package/dist/src/agents/simulator.executor.js +41 -9
  14. package/dist/src/agents/simulator.js +86 -28
  15. package/dist/src/agents/simulator.prompts.d.ts +3 -2
  16. package/dist/src/agents/simulator.prompts.js +52 -78
  17. package/dist/src/agents/simulator.types.d.ts +20 -5
  18. package/dist/src/agents/simulator.utils.d.ts +7 -2
  19. package/dist/src/agents/simulator.utils.js +33 -11
  20. package/dist/src/agents/system.js +1 -2
  21. package/dist/src/execute.d.ts +17 -3
  22. package/dist/src/execute.js +156 -158
  23. package/dist/src/index.d.ts +1 -1
  24. package/dist/src/index.js +1 -1
  25. package/dist/src/{princing.openai.d.ts → pricing.llm.d.ts} +6 -0
  26. package/dist/src/pricing.llm.js +234 -0
  27. package/dist/src/prompts.d.ts +13 -4
  28. package/dist/src/prompts.js +221 -114
  29. package/dist/src/rag/embeddings.d.ts +36 -18
  30. package/dist/src/rag/embeddings.js +125 -128
  31. package/dist/src/rag/index.d.ts +5 -5
  32. package/dist/src/rag/index.js +14 -17
  33. package/dist/src/rag/parser.d.ts +2 -1
  34. package/dist/src/rag/parser.js +11 -14
  35. package/dist/src/rag/rag.examples.d.ts +27 -0
  36. package/dist/src/rag/rag.examples.js +151 -0
  37. package/dist/src/rag/rag.manager.d.ts +383 -0
  38. package/dist/src/rag/rag.manager.js +1378 -0
  39. package/dist/src/rag/types.d.ts +128 -12
  40. package/dist/src/rag/types.js +100 -1
  41. package/dist/src/rag/usecase.d.ts +37 -0
  42. package/dist/src/rag/usecase.js +96 -7
  43. package/dist/src/rules/git/git.e2e.helper.js +1 -0
  44. package/dist/src/rules/git/git.health.d.ts +57 -0
  45. package/dist/src/rules/git/git.health.js +281 -1
  46. package/dist/src/rules/git/index.d.ts +2 -2
  47. package/dist/src/rules/git/index.js +12 -1
  48. package/dist/src/rules/git/repo.d.ts +117 -0
  49. package/dist/src/rules/git/repo.js +536 -0
  50. package/dist/src/rules/git/repo.tools.d.ts +22 -1
  51. package/dist/src/rules/git/repo.tools.js +50 -1
  52. package/dist/src/rules/types.d.ts +16 -14
  53. package/dist/src/rules/utils.matter.d.ts +0 -4
  54. package/dist/src/rules/utils.matter.js +26 -7
  55. package/dist/src/scrapper.d.ts +15 -22
  56. package/dist/src/scrapper.js +57 -110
  57. package/dist/src/stategraph/index.d.ts +1 -1
  58. package/dist/src/stategraph/stategraph.d.ts +31 -2
  59. package/dist/src/stategraph/stategraph.js +93 -6
  60. package/dist/src/stategraph/stategraph.storage.js +4 -0
  61. package/dist/src/stategraph/types.d.ts +22 -0
  62. package/dist/src/types.d.ts +4 -2
  63. package/dist/src/types.js +1 -1
  64. package/dist/src/usecase.d.ts +11 -2
  65. package/dist/src/usecase.js +27 -35
  66. package/dist/src/utils.d.ts +32 -18
  67. package/dist/src/utils.js +60 -126
  68. package/package.json +7 -2
  69. package/dist/src/agents/digestor.test.d.ts +0 -1
  70. package/dist/src/agents/digestor.test.js +0 -45
  71. package/dist/src/agents/reducer.example.d.ts +0 -28
  72. package/dist/src/agents/reducer.example.js +0 -118
  73. package/dist/src/agents/reducer.process.d.ts +0 -16
  74. package/dist/src/agents/reducer.process.js +0 -143
  75. package/dist/src/agents/reducer.tools.d.ts +0 -29
  76. package/dist/src/agents/reducer.tools.js +0 -157
  77. package/dist/src/agents/simpleExample.d.ts +0 -3
  78. package/dist/src/agents/simpleExample.js +0 -38
  79. package/dist/src/agents/system-review.d.ts +0 -5
  80. package/dist/src/agents/system-review.js +0 -181
  81. package/dist/src/agents/systemReview.d.ts +0 -4
  82. package/dist/src/agents/systemReview.js +0 -22
  83. package/dist/src/princing.openai.js +0 -54
  84. package/dist/src/rag/tools.d.ts +0 -76
  85. package/dist/src/rag/tools.js +0 -196
  86. package/dist/src/rules/user.mapper.d.ts +0 -61
  87. package/dist/src/rules/user.mapper.js +0 -160
  88. package/dist/src/rules/utils/slug.d.ts +0 -22
  89. package/dist/src/rules/utils/slug.js +0 -35
@@ -30,6 +30,7 @@ class AgentStateGraph {
30
30
  description: description,
31
31
  messages: [],
32
32
  usage: { prompt: 0, completion: 0, total: 0, cost: 0 },
33
+ trailSteps: [], // ✅ Chaque discussion a son propre trail
33
34
  createdAt: new Date(),
34
35
  updatedAt: new Date(),
35
36
  startAgent: agentName
@@ -56,7 +57,7 @@ class AgentStateGraph {
56
57
  /**
57
58
  * Écrase le message system de la discussion avec un nouvel agent
58
59
  * Le message system est toujours messages[0] avec role: "system"
59
- * @param agentName Nom de l'agent
60
+ * @param agentName Nom de l'agent (clé de discussion, reste fixe)
60
61
  * @param content Nouveau contenu du message system
61
62
  */
62
63
  set(agentName, content) {
@@ -64,8 +65,8 @@ class AgentStateGraph {
64
65
  const systemMessage = {
65
66
  id: (0, crypto_1.randomUUID)(),
66
67
  role: 'system',
67
- content,
68
- agent: agentName,
68
+ content: content,
69
+ agent: agentName, // Tag avec la clé de discussion
69
70
  timestamp: new Date()
70
71
  };
71
72
  // Écraser ou créer le message system (toujours en position 0)
@@ -73,8 +74,69 @@ class AgentStateGraph {
73
74
  discussion.messages.push(systemMessage);
74
75
  }
75
76
  else {
76
- discussion.messages[0] = systemMessage;
77
+ discussion.messages[0].content = content;
78
+ discussion.messages[0].agent = systemMessage.agent;
79
+ discussion.messages[0].timestamp = new Date();
80
+ }
81
+ this.updateSystemMessage(discussion);
82
+ discussion.updatedAt = new Date();
83
+ }
84
+ /**
85
+ * Ajoute une étape au CONTEXT TRAIL et met à jour le message system
86
+ * @param agentName Nom de l'agent
87
+ * @param step Étape à ajouter au trail
88
+ */
89
+ addStep(agentName, step) {
90
+ const discussion = this.discussions.find(d => d.startAgent === agentName);
91
+ if (!discussion)
92
+ return;
93
+ discussion.trailSteps.push(step);
94
+ this.updateSystemMessage(discussion);
95
+ }
96
+ /**
97
+ * Retourne tous les steps du CONTEXT TRAIL pour une discussion
98
+ * @param agentName Nom de l'agent
99
+ * @returns Liste des steps enregistrés pour cette discussion
100
+ */
101
+ steps(agentName) {
102
+ const discussion = this.discussions.find(d => d.startAgent === agentName);
103
+ // console.log(`🔍 steps: ${agentName} has ${discussion?.trailSteps.length} steps`);
104
+ return discussion ? [...discussion.trailSteps] : [];
105
+ }
106
+ /**
107
+ * Formate le CONTEXT TRAIL d'une discussion pour injection dans system instructions
108
+ * @param discussion Discussion à formater
109
+ * @returns Trail formaté ou message par défaut
110
+ */
111
+ formatTrailPrompt(discussion) {
112
+ if (discussion.trailSteps.length === 0) {
113
+ return '(No actions yet)';
114
+ }
115
+ return discussion.trailSteps.map(s => {
116
+ const idPart = s.id ? ` [id: ${s.id}]` : '';
117
+ return `- ${s.tool}: ${s.context} "${s.reason}"${idPart}`;
118
+ }).join('\n');
119
+ }
120
+ /**
121
+ * Met à jour le message system avec le nouveau trail via regexp
122
+ * @param agentName Nom de l'agent
123
+ */
124
+ updateSystemMessage(discussion) {
125
+ const systemMessage = discussion.messages.find((m) => m.role === 'system');
126
+ if (!systemMessage)
127
+ return;
128
+ const trail = this.formatTrailPrompt(discussion);
129
+ const trailBlock = `<context-trail>\n${trail}\n</context-trail>`;
130
+ const hasTag = systemMessage.content.includes('<context-trail>');
131
+ // Remplacement via regexp du tag <context-trail>
132
+ if (hasTag) {
133
+ systemMessage.content = systemMessage.content.replace(/<context-trail>[\s\S]*?<\/context-trail>/, trailBlock);
134
+ }
135
+ else {
136
+ // Ajouter le tag si absent
137
+ systemMessage.content += `\n\n${trailBlock}`;
77
138
  }
139
+ systemMessage.timestamp = new Date();
78
140
  discussion.updatedAt = new Date();
79
141
  }
80
142
  /**
@@ -107,9 +169,9 @@ class AgentStateGraph {
107
169
  }
108
170
  return content;
109
171
  };
110
- // Filtrer les messages pour le client - exclure system et tool
172
+ // Filtrer les messages pour le client - exclure system, tool et messages avec name
111
173
  const clientMessages = discussion.messages
112
- .filter(msg => msg.role !== 'system' && !msg.name)
174
+ .filter(msg => msg.role !== 'system' && msg.role !== 'tool' && !msg.name)
113
175
  .map(msg => ({
114
176
  id: msg.id,
115
177
  role: msg.role,
@@ -162,6 +224,7 @@ class AgentStateGraph {
162
224
  discussion.messages = [];
163
225
  }
164
226
  // Réinitialiser l'usage
227
+ discussion.trailSteps = [];
165
228
  discussion.usage = { prompt: 0, completion: 0, total: 0, cost: 0 };
166
229
  discussion.updatedAt = new Date();
167
230
  }
@@ -211,6 +274,29 @@ class AgentStateGraph {
211
274
  }
212
275
  return agentName;
213
276
  }
277
+ /**
278
+ * Charge une discussion en remplaçant l'existante ou en créant une nouvelle
279
+ * Recherche par id en priorité, sinon par startAgent
280
+ * @param discussion Discussion à charger
281
+ */
282
+ load(discussion) {
283
+ // Chercher discussion existante par id OU par startAgent
284
+ const index = this.discussions.findIndex(d => d.id === discussion.id || d.startAgent === discussion.startAgent);
285
+ if (index >= 0) {
286
+ // Remplacer l'existante
287
+ this.discussions[index] = {
288
+ ...discussion,
289
+ updatedAt: new Date()
290
+ };
291
+ }
292
+ else {
293
+ // Créer nouvelle
294
+ this.discussions.push({
295
+ ...discussion,
296
+ updatedAt: new Date()
297
+ });
298
+ }
299
+ }
214
300
  /**
215
301
  * Sérialise le StateGraph en JSON
216
302
  * @returns Représentation JSON
@@ -230,6 +316,7 @@ class AgentStateGraph {
230
316
  ...d,
231
317
  createdAt: new Date(d.createdAt),
232
318
  updatedAt: new Date(d.updatedAt),
319
+ trailSteps: d.trailSteps || [], // ✅ Rétrocompatibilité : initialiser vide si absent
233
320
  messages: d.messages.map((m) => ({
234
321
  ...m,
235
322
  timestamp: new Date(m.timestamp)
@@ -71,6 +71,10 @@ function sessionStateGraphSet(context, stateGraph) {
71
71
  const compressed = (0, zlib_1.gzipSync)(Buffer.from(jsonData, 'utf8'));
72
72
  // Stocker en base64 dans la session
73
73
  session[SESSION_STATEGRAPH_KEY] = compressed.toString('base64');
74
+ // Force express-session à marquer la session comme modifiée
75
+ if (typeof session.touch === 'function') {
76
+ session.touch();
77
+ }
74
78
  // Logging pour debug (taille avant/après compression)
75
79
  if (process.env.NODE_ENV === 'development') {
76
80
  const originalSize = Buffer.byteLength(jsonData, 'utf8');
@@ -33,6 +33,20 @@ export interface TokenUsage {
33
33
  /** Coût estimé en USD (optionnel) */
34
34
  cost?: number;
35
35
  }
36
+ /**
37
+ * Step du CONTEXT TRAIL - trace une action significative
38
+ * Utilisé pour maintenir une mémoire de travail des actions effectuées par les outils
39
+ */
40
+ export interface StepTrail {
41
+ /** Nom de l'outil (ex: "transferAgents", "database") */
42
+ tool: string;
43
+ /** Contexte de l'action (ex: "orientation → guess-word") */
44
+ context: string;
45
+ /** Justification/raison de l'action */
46
+ reason: string;
47
+ /** ID optionnel pour détection de boucles */
48
+ id?: string;
49
+ }
36
50
  /**
37
51
  * Discussion d'agent - thread de messages pour un agent spécifique
38
52
  * Remplace l'ancienne AgenticMemorySession
@@ -48,6 +62,8 @@ export interface AgentDiscussion {
48
62
  messages: AgentMessage[];
49
63
  /** Usage des tokens pour cette discussion */
50
64
  usage: TokenUsage;
65
+ /** CONTEXT TRAIL - steps des actions significatives */
66
+ trailSteps: StepTrail[];
51
67
  /** Date de création */
52
68
  createdAt: Date;
53
69
  /** Date de dernière mise à jour */
@@ -104,6 +120,12 @@ export interface AgentStateGraph {
104
120
  * @returns true si le message a été supprimé, false s'il n'a pas été trouvé
105
121
  */
106
122
  deleteMessage(agentName: string, messageId: string): boolean;
123
+ /**
124
+ * Charge une discussion en remplaçant l'existante ou en créant une nouvelle
125
+ * Cherche par id OU par startAgent
126
+ * @param discussion Discussion à charger
127
+ */
128
+ load(discussion: AgentDiscussion): void;
107
129
  }
108
130
  /**
109
131
  * Vue client d'une discussion (filtrée)
@@ -33,6 +33,7 @@ export interface AgentModel {
33
33
  temperature: null;
34
34
  maxTokens: number;
35
35
  topP?: number;
36
+ stream?: boolean;
36
37
  parallel_tool_calls: boolean;
37
38
  frequencyPenalty?: number;
38
39
  presencePenalty?: number;
@@ -47,7 +48,8 @@ export interface AgentModel {
47
48
  }
48
49
  export interface AgentConfig {
49
50
  name: string;
50
- model: AgentModel;
51
+ groupName?: string;
52
+ model: string;
51
53
  human?: boolean;
52
54
  publicDescription: string;
53
55
  instructions: string;
@@ -65,8 +67,8 @@ export interface AgentConfig {
65
67
  export interface UserNano {
66
68
  id: string;
67
69
  isAnonymous?: boolean;
68
- role: string;
69
70
  uid?: string;
71
+ [key: string]: any;
70
72
  }
71
73
  export type AgenticCache = {
72
74
  get: <T>(key: string) => Promise<T | null>;
package/dist/src/types.js CHANGED
@@ -42,7 +42,7 @@ function executionResultMerge(a, b) {
42
42
  const merged = {
43
43
  runId: a.runId && a.runId.length > 0 ? a.runId : b.runId,
44
44
  startQuery: a.startQuery || b.startQuery || '',
45
- actions: [...(a.actions || []), ...(b.actions || [])],
45
+ actions: [],
46
46
  lastMessage: a.lastMessage || '',
47
47
  usage: {
48
48
  prompt: (a.usage?.prompt || 0) + (b.usage?.prompt || 0),
@@ -1,4 +1,13 @@
1
- export declare function callGPTToExtractUserQueries(inputsection: string, file: string): Promise<{
2
- json: any;
1
+ import { UsecaseExtractionOptions } from "./prompts";
2
+ /**
3
+ * Extrait les use cases d'une section de document en utilisant un LLM via executeQuery
4
+ *
5
+ * @param inputsection - Le contenu de la section à analyser
6
+ * @param file - Le nom du fichier source
7
+ * @param options - Options d'extraction (optionnel)
8
+ * @returns Promise avec le JSON des queries et le coût
9
+ */
10
+ export declare function llmExtractUserQueries(inputsection: string, file: string, options?: UsecaseExtractionOptions): Promise<{
11
+ json: string;
3
12
  cost: number;
4
13
  }>;
@@ -1,44 +1,36 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.callGPTToExtractUserQueries = callGPTToExtractUserQueries;
4
- const princing_openai_1 = require("./princing.openai");
3
+ exports.llmExtractUserQueries = llmExtractUserQueries;
5
4
  const prompts_1 = require("./prompts");
6
- const utils_1 = require("./utils");
7
- async function callGPTToExtractUserQueries(inputsection, file) {
8
- const openai = (0, utils_1.openaiInstance)();
5
+ const execute_1 = require("./execute");
6
+ /**
7
+ * Extrait les use cases d'une section de document en utilisant un LLM via executeQuery
8
+ *
9
+ * @param inputsection - Le contenu de la section à analyser
10
+ * @param file - Le nom du fichier source
11
+ * @param options - Options d'extraction (optionnel)
12
+ * @returns Promise avec le JSON des queries et le coût
13
+ */
14
+ async function llmExtractUserQueries(inputsection, file, options = { model: "LOW-fast" }) {
9
15
  // Format: YYYY-MM-DD
10
16
  const today = new Date().toISOString().substring(0, 10);
11
- // Créer le prompt pour décrire la tâche au LLM
12
- const messages = [
13
- {
14
- role: "system",
15
- content: (0, prompts_1.usecaseExtractionPrompt)(file)
16
- },
17
- {
18
- role: "user",
19
- content: `Nous sommes le ${today}.\nVoici le document à analyser :\n${inputsection}`
20
- }
21
- ];
22
- // WARNING: o3-mini is buggy with "Marche à suivre nouveau bail.pdf"
23
- //const model = "o3-mini";// "gpt-4o-mini";
24
- const model = "gpt-5-mini";
25
- const response = await openai.chat.completions.create({
26
- model: model,
27
- reasoning_effort: "low",
28
- verbosity: "low",
29
- messages,
30
- //reasoning_effort:"low",
31
- response_format: { type: "json_object" }
32
- });
17
+ // Construire le prompt complet en combinant système et utilisateur
18
+ const systemPrompt = (0, prompts_1.usecaseExtractionPrompt)(file);
19
+ const userContent = `Nous sommes le ${today}.\nVoici le document à analyser :\n${inputsection}`;
20
+ // Combiner les prompts pour executeQuery (qui prend un seul message utilisateur)
21
+ const query = `${systemPrompt}\n\n---\n\n${userContent}`;
22
+ //
23
+ // Utiliser executeQuery pour exécuter la requête
33
24
  // response_format: { type: "json_object" }
34
- const cost = (0, princing_openai_1.calculateCost)(model, response.usage);
35
- // Récupérer la réponse markdown
36
- const json = response.choices[0].message.content;
25
+ const result = await (0, execute_1.executeQuery)({
26
+ query,
27
+ home: options.model,
28
+ stdout: execute_1.DummyWritable,
29
+ verbose: false,
30
+ json: true
31
+ });
32
+ const json = result.content;
33
+ const cost = result.usage.cost;
37
34
  console.log(`Markdown 💰 cost: ${cost}`);
38
- //
39
- // add a regex to extract the markdown content between <thinking></thinking> tags
40
- // const thinking = markdown.match(/<thinking>[\s\S]*?<\/thinking>/)?.[0];
41
- // const markdownWithoutThinking = markdown.replace(/<thinking>[\s\S]*?<\/thinking>/g, '');
42
- // return markdownWithoutThinking;
43
35
  return { json, cost };
44
36
  }
@@ -1,6 +1,13 @@
1
1
  import { ParsedFunctionToolCall } from "openai/resources/beta/chat/completions";
2
2
  import { AgentConfig, AgenticContext } from "./types";
3
- export declare const openaiInstance: (openai?: any) => any;
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;
4
11
  /**
5
12
  * Converts a string to a URL-friendly slug
6
13
  * @param text The text to convert to a slug
@@ -8,27 +15,34 @@ export declare const openaiInstance: (openai?: any) => any;
8
15
  * @returns A URL-friendly slug
9
16
  */
10
17
  export declare const toSlug: (text: string, whitespace?: string) => string;
18
+ /**
19
+ * Contrat standard JSON pour le transfert (handoff) entre agents.
20
+ *
21
+ * Ce contrat décrit le format attendu lors d'un transfert via l'outil "transferAgents".
22
+ * Il doit être inclut dans la documentation de l'outil pour garantir l'interopérabilité.
23
+ *
24
+ * Exemple de contrat (format JSON) :
25
+ *
26
+ * ```json
27
+ * {
28
+ * "subject_id": "sha1(intention_normalisee_id|bien|acteur)", // Identifiant unique du sujet
29
+ * "intention": "<string>", // Intention normalisée de la demande
30
+ * "decision_preliminaire": "S1|S2|S3", // Décision préliminaire prise (catégorisation)
31
+ * "meme_sujet_bons_ouverts": "string", // Identifiants ou liens vers dossiers ouverts liés au même sujet
32
+ * "urgency": "standard|prioritaire|urgent", // Niveau d'urgence de la demande
33
+ * "mood": "<string>", // État émotionnel détecté ou exprimé
34
+ * "next_action": "<string>", // Prochaine action préconisée ou à effectuer
35
+ * "multiple_subjects": "string" // Autres sujets/discussions associés (optionnel)
36
+ * }
37
+ * ```
38
+ *
39
+ * À intégrer dans la définition des outils de transfert pour chaque agent métier impliqué dans un handoff.
40
+ */
11
41
  /**
12
42
  * This defines and adds "transferAgents" tool dynamically based on the specified downstreamAgents on each agent.
43
+ * https://github.com/openai/openai-realtime-agents/blob/without-agents-sdk/src/app/agentConfigs/utils.ts
13
44
  */
14
45
  export declare function injectTransferTools(agentDefs: AgentConfig[]): AgentConfig[];
15
46
  export declare function handleTransferCall(discussion: any, currentAgentRef: {
16
47
  name: string;
17
48
  }, agents: AgentConfig[], functionCallParams: ParsedFunctionToolCall, context: AgenticContext): Promise<any>;
18
- /**
19
- * Calls the system review agent to analyze a prompt
20
- *
21
- * This function sends a prompt to the system review agent and returns its analysis.
22
- * The system review agent evaluates prompts based on various criteria like clarity,
23
- * identity, scope, decision logic, etc.
24
- *
25
- * @param {string} prompt - The prompt text to be analyzed by the system review agent
26
- * @param {Object} params - Parameters for the API call
27
- * @param {Object} params.openai - The OpenAI client instance
28
- * @param {Object} params.defaultOptions - Default options to be merged with agent model options
29
- * @returns {Promise<string>} The analysis response from the system review agent
30
- */
31
- export declare function callForSystemReview(prompt: string, params: any): Promise<{
32
- content: any;
33
- cost: number;
34
- }>;
package/dist/src/utils.js CHANGED
@@ -1,21 +1,32 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.toSlug = exports.openaiInstance = void 0;
4
7
  exports.injectTransferTools = injectTransferTools;
5
8
  exports.handleTransferCall = handleTransferCall;
6
- exports.callForSystemReview = callForSystemReview;
7
9
  const prompts_1 = require("./prompts");
8
- const system_1 = require("./agents/system");
9
- const princing_openai_1 = require("./princing.openai");
10
- let _openaiInstance;
11
- const openaiInstance = function (openai) {
12
- if (openai) {
13
- _openaiInstance = openai;
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
+ const options = {
19
+ apiKey: process.env[envKey],
20
+ timeout: 60000 * 15
21
+ };
22
+ if (baseUrl) {
23
+ options.baseURL = baseUrl;
14
24
  }
15
- if (!_openaiInstance) {
25
+ globalThis._openaiInstance_ = new openai_1.default(options);
26
+ if (!globalThis._openaiInstance_) {
16
27
  throw new Error('OpenAI instance has not been initialized');
17
28
  }
18
- return _openaiInstance;
29
+ return globalThis._openaiInstance_;
19
30
  };
20
31
  exports.openaiInstance = openaiInstance;
21
32
  /**
@@ -40,8 +51,32 @@ const toSlug = (text, whitespace = '-') => {
40
51
  .replace(new RegExp(`^\\${whitespace}+|\\${whitespace}+$`, 'g'), ''); // Trim whitespace char (escape for regex)
41
52
  };
42
53
  exports.toSlug = toSlug;
54
+ /**
55
+ * Contrat standard JSON pour le transfert (handoff) entre agents.
56
+ *
57
+ * Ce contrat décrit le format attendu lors d'un transfert via l'outil "transferAgents".
58
+ * Il doit être inclut dans la documentation de l'outil pour garantir l'interopérabilité.
59
+ *
60
+ * Exemple de contrat (format JSON) :
61
+ *
62
+ * ```json
63
+ * {
64
+ * "subject_id": "sha1(intention_normalisee_id|bien|acteur)", // Identifiant unique du sujet
65
+ * "intention": "<string>", // Intention normalisée de la demande
66
+ * "decision_preliminaire": "S1|S2|S3", // Décision préliminaire prise (catégorisation)
67
+ * "meme_sujet_bons_ouverts": "string", // Identifiants ou liens vers dossiers ouverts liés au même sujet
68
+ * "urgency": "standard|prioritaire|urgent", // Niveau d'urgence de la demande
69
+ * "mood": "<string>", // État émotionnel détecté ou exprimé
70
+ * "next_action": "<string>", // Prochaine action préconisée ou à effectuer
71
+ * "multiple_subjects": "string" // Autres sujets/discussions associés (optionnel)
72
+ * }
73
+ * ```
74
+ *
75
+ * À intégrer dans la définition des outils de transfert pour chaque agent métier impliqué dans un handoff.
76
+ */
43
77
  /**
44
78
  * This defines and adds "transferAgents" tool dynamically based on the specified downstreamAgents on each agent.
79
+ * https://github.com/openai/openai-realtime-agents/blob/without-agents-sdk/src/app/agentConfigs/utils.ts
45
80
  */
46
81
  function injectTransferTools(agentDefs) {
47
82
  // Iterate over each agent definition
@@ -50,67 +85,18 @@ function injectTransferTools(agentDefs) {
50
85
  return;
51
86
  }
52
87
  const downstreamAgents = agentDef.downstreamAgents || [];
53
- //
54
- // Add the think tool if maxSteps is set
55
- // https://www.aihero.dev/implementing-anthropics-think-tool-in-typescript
56
- if (agentDef.maxSteps && agentDef.maxSteps > 0) {
57
- const description = `
58
- Use the tool as a helper to think about something with a plan of multiple steps.
59
- It will not obtain new information or change the database, but just append the thought to the log.
60
- Use it when complex reasoning or some cache memory is needed.
61
- To avoid infinite thinking, the tool is limited to ${agentDef.maxSteps} calls.
62
-
63
- It takes two arguments:
64
- - thought (str): A thought to think about.
65
- - step (int): The incremented step number that constrains the global thinking with a limitation of ${agentDef.maxSteps} calls.
66
- `;
67
- const think = {
68
- type: "function",
69
- function: {
70
- name: "thinking",
71
- description,
72
- strict: true,
73
- parameters: {
74
- type: "object",
75
- properties: {
76
- justification: {
77
- type: "string",
78
- description: "The reasoning why this thinking is needed.",
79
- },
80
- thought: {
81
- type: "string",
82
- description: "A thought to think about.",
83
- },
84
- step: {
85
- type: "number",
86
- description: "The incremented step number that constrains the global thinking.",
87
- },
88
- },
89
- required: ["justification", "thought", "step"],
90
- additionalProperties: false,
91
- },
92
- }
93
- };
94
- // Ensure the agent has a tools array
95
- if (!agentDef.tools) {
96
- agentDef.tools = [];
97
- }
98
- console.log('--- DBG addTools', agentDef.name, 'with think step', agentDef.maxSteps);
99
- // Add the newly created tool to the current agent's tools
100
- agentDef.tools.push(think);
101
- }
102
88
  // Only proceed if there are downstream agents
103
89
  if (downstreamAgents.length > 0) {
104
90
  // Build a list of downstream agents and their descriptions for the prompt
105
91
  const availableAgentsList = downstreamAgents
106
- .map((dAgent) => `- ${dAgent.name}: ${dAgent.publicDescription ?? "No description"} ${dAgent.human ? '(human agent, less specialized)' : ''}`)
92
+ .map((dAgent) => `- ${dAgent.name}: ${dAgent.publicDescription ?? "No description"} ${dAgent.human ? '(⚠️ root agent for orientation)' : ''}`)
107
93
  .join("\n");
108
94
  // Create the transfer_agent tool specific to this agent
109
95
  const transferAgentTool = {
110
96
  type: "function",
111
97
  function: {
112
98
  name: "transferAgents",
113
- description: `${prompts_1.transferAgentPrompt.replace('__AGENT_NAME__', agentDef.name)}
99
+ description: `${prompts_1.transferAgentPromptStructured.replace('__AGENT_NAME__', agentDef.name)}
114
100
  ${availableAgentsList}
115
101
  `,
116
102
  parameters: {
@@ -126,7 +112,7 @@ ${availableAgentsList}
126
112
  },
127
113
  destination_agent: {
128
114
  type: "string",
129
- description: "The more specialized destination_agent that should handle the users intended request.",
115
+ description: "The more specialized destination_agent that should handle the user's intended request.",
130
116
  enum: downstreamAgents.map((dAgent) => dAgent.name),
131
117
  },
132
118
  confidence: {
@@ -151,7 +137,7 @@ ${availableAgentsList}
151
137
  }
152
138
  // Add the newly created tool to the current agent's tools
153
139
  agentDef.tools.push(transferAgentTool);
154
- // console.log('--- DBG injectTransferTools',agentDef.name,'with new transfer',JSON.stringify(transferAgentTool.function.parameters,null,2 ));
140
+ // console.log('--- DBG injectTransferTools',agentDef.name,transferAgentTool.function.description);
155
141
  }
156
142
  // so .stringify doesn't break with circular dependencies
157
143
  agentDef.downstreamAgents = agentDef.downstreamAgents?.map(({ name, publicDescription, human }) => ({
@@ -194,18 +180,25 @@ async function handleTransferCall(discussion, currentAgentRef, agents, functionC
194
180
  if (destinationAgent) {
195
181
  //console.log(`🤖 Agent "${destinationAgent.name}" en préparation`);
196
182
  currentAgentRef.name = destinationAgent.name;
183
+ //
184
+ // Generate ID for CONTEXT TRAIL (loop detection)
185
+ const transferId = (0, exports.toSlug)(args.rationale_for_transfer);
197
186
  return {
198
- feedback: args.rationale_for_transfer,
187
+ name: functionCallParams.function.name, // ← tool pour addStep
188
+ feedback: args.rationale_for_transfer, // ← reason pour addStep
189
+ context: `${currentAgentName} → ${destinationAgentName}`, // ← context pour addStep
190
+ id: transferId, // ← ID optionnel pour addStep
199
191
  destination_agent: destinationAgentName,
200
192
  source_agent: currentAgentName,
201
- did_transfer: true,
202
- name: functionCallParams.function.name
193
+ content: '', // ✅ Transfert silencieux
194
+ did_transfer: true
203
195
  };
204
196
  }
205
197
  else {
206
- console.log(" Agent non trouvé !");
198
+ console.log(`❌L'agent destination "${destinationAgentName}" n'a pas été trouvé.`);
207
199
  return {
208
- feedback: "L'agent destination n'a pas été trouvé.",
200
+ feedback: `❌ L'agent destination "${destinationAgentName}" n'a pas été trouvé.`,
201
+ content: `❌L'agent destination "${destinationAgentName}" n'a pas été trouvé.`,
209
202
  did_transfer: false,
210
203
  name: functionCallParams.function.name
211
204
  };
@@ -244,62 +237,3 @@ async function handleTransferCall(discussion, currentAgentRef, agents, functionC
244
237
  };
245
238
  }
246
239
  }
247
- /**
248
- * Calls the system review agent to analyze a prompt
249
- *
250
- * This function sends a prompt to the system review agent and returns its analysis.
251
- * The system review agent evaluates prompts based on various criteria like clarity,
252
- * identity, scope, decision logic, etc.
253
- *
254
- * @param {string} prompt - The prompt text to be analyzed by the system review agent
255
- * @param {Object} params - Parameters for the API call
256
- * @param {Object} params.openai - The OpenAI client instance
257
- * @param {Object} params.defaultOptions - Default options to be merged with agent model options
258
- * @returns {Promise<string>} The analysis response from the system review agent
259
- */
260
- async function callForSystemReview(prompt, params) {
261
- const { openai, defaultOptions } = params;
262
- const agent = system_1.system;
263
- const options = Object.assign({}, agent.model, defaultOptions || {});
264
- const jsonOptions = `
265
- - L'option JSON a été activée, tu dois respecter le format brut suivant \`
266
- {
267
- directives: [
268
- {"directive": "...","criteria": [{"criterion": "...","score": "...","comment": "..."}]},
269
- ...
270
- ]
271
- }
272
- \``;
273
- //
274
- // add the initial agent to his memory
275
- // Handle two-shot prompting: if instructions is an array, use the first part as a system message
276
- const instructions = agent.instructions;
277
- options.messages = [
278
- { role: "system", content: instructions }
279
- ];
280
- if (options.response_format?.type == "json_object") {
281
- options.messages.push({ role: "user", content: jsonOptions });
282
- }
283
- options.messages.push({ role: "user", content: `tu dois analyser toutes les directives:\n ${prompt}` });
284
- let thinking = 1;
285
- //
286
- // loop until the agent has finished thinking
287
- do {
288
- const response = await openai.chat.completions.create(options);
289
- const cost = (0, princing_openai_1.calculateCost)(options.model, response.usage);
290
- if (options.response_format?.type == "json_object") {
291
- const content = JSON.parse(response.choices[0].message.content || '{}');
292
- return { content, cost };
293
- }
294
- // Handle two-shot prompting: if instructions is an array, send the second part as a user message
295
- // This allows for more complex agent behavior by providing additional context or instructions
296
- // after the initial response, similar to chain-of-thought prompting
297
- if (!Array.isArray(agent.instructions) || thinking >= agent.instructions.length) {
298
- const content = response.choices[0].message.content;
299
- return { content, cost };
300
- }
301
- const instructions = agent.instructions[thinking];
302
- options.messages.push({ role: "user", content: instructions });
303
- thinking++;
304
- } while (true);
305
- }