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.
- package/dist/src/agents/agents.example.js +21 -22
- package/dist/src/agents/authentication.js +1 -2
- package/dist/src/agents/prompts.d.ts +5 -4
- package/dist/src/agents/prompts.js +42 -87
- package/dist/src/agents/reducer.core.d.ts +24 -2
- package/dist/src/agents/reducer.core.js +125 -35
- package/dist/src/agents/reducer.loaders.d.ts +55 -1
- package/dist/src/agents/reducer.loaders.js +114 -1
- package/dist/src/agents/reducer.types.d.ts +45 -2
- package/dist/src/agents/semantic.js +1 -2
- package/dist/src/agents/simulator.d.ts +4 -0
- package/dist/src/agents/simulator.executor.d.ts +5 -1
- package/dist/src/agents/simulator.executor.js +41 -9
- package/dist/src/agents/simulator.js +86 -28
- package/dist/src/agents/simulator.prompts.d.ts +3 -2
- package/dist/src/agents/simulator.prompts.js +52 -78
- package/dist/src/agents/simulator.types.d.ts +20 -5
- package/dist/src/agents/simulator.utils.d.ts +7 -2
- package/dist/src/agents/simulator.utils.js +33 -11
- package/dist/src/agents/system.js +1 -2
- package/dist/src/execute.d.ts +17 -3
- package/dist/src/execute.js +156 -158
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.js +1 -1
- package/dist/src/{princing.openai.d.ts → pricing.llm.d.ts} +6 -0
- package/dist/src/pricing.llm.js +234 -0
- package/dist/src/prompts.d.ts +13 -4
- package/dist/src/prompts.js +221 -114
- package/dist/src/rag/embeddings.d.ts +36 -18
- package/dist/src/rag/embeddings.js +125 -128
- package/dist/src/rag/index.d.ts +5 -5
- package/dist/src/rag/index.js +14 -17
- package/dist/src/rag/parser.d.ts +2 -1
- package/dist/src/rag/parser.js +11 -14
- package/dist/src/rag/rag.examples.d.ts +27 -0
- package/dist/src/rag/rag.examples.js +151 -0
- package/dist/src/rag/rag.manager.d.ts +383 -0
- package/dist/src/rag/rag.manager.js +1378 -0
- package/dist/src/rag/types.d.ts +128 -12
- package/dist/src/rag/types.js +100 -1
- package/dist/src/rag/usecase.d.ts +37 -0
- package/dist/src/rag/usecase.js +96 -7
- package/dist/src/rules/git/git.e2e.helper.js +1 -0
- package/dist/src/rules/git/git.health.d.ts +57 -0
- package/dist/src/rules/git/git.health.js +281 -1
- package/dist/src/rules/git/index.d.ts +2 -2
- package/dist/src/rules/git/index.js +12 -1
- package/dist/src/rules/git/repo.d.ts +117 -0
- package/dist/src/rules/git/repo.js +536 -0
- package/dist/src/rules/git/repo.tools.d.ts +22 -1
- package/dist/src/rules/git/repo.tools.js +50 -1
- package/dist/src/rules/types.d.ts +16 -14
- package/dist/src/rules/utils.matter.d.ts +0 -4
- package/dist/src/rules/utils.matter.js +26 -7
- package/dist/src/scrapper.d.ts +15 -22
- package/dist/src/scrapper.js +57 -110
- package/dist/src/stategraph/index.d.ts +1 -1
- package/dist/src/stategraph/stategraph.d.ts +31 -2
- package/dist/src/stategraph/stategraph.js +93 -6
- package/dist/src/stategraph/stategraph.storage.js +4 -0
- package/dist/src/stategraph/types.d.ts +22 -0
- package/dist/src/types.d.ts +4 -2
- package/dist/src/types.js +1 -1
- package/dist/src/usecase.d.ts +11 -2
- package/dist/src/usecase.js +27 -35
- package/dist/src/utils.d.ts +32 -18
- package/dist/src/utils.js +60 -126
- package/package.json +7 -2
- package/dist/src/agents/digestor.test.d.ts +0 -1
- package/dist/src/agents/digestor.test.js +0 -45
- package/dist/src/agents/reducer.example.d.ts +0 -28
- package/dist/src/agents/reducer.example.js +0 -118
- package/dist/src/agents/reducer.process.d.ts +0 -16
- package/dist/src/agents/reducer.process.js +0 -143
- package/dist/src/agents/reducer.tools.d.ts +0 -29
- package/dist/src/agents/reducer.tools.js +0 -157
- package/dist/src/agents/simpleExample.d.ts +0 -3
- package/dist/src/agents/simpleExample.js +0 -38
- package/dist/src/agents/system-review.d.ts +0 -5
- package/dist/src/agents/system-review.js +0 -181
- package/dist/src/agents/systemReview.d.ts +0 -4
- package/dist/src/agents/systemReview.js +0 -22
- package/dist/src/princing.openai.js +0 -54
- package/dist/src/rag/tools.d.ts +0 -76
- package/dist/src/rag/tools.js +0 -196
- package/dist/src/rules/user.mapper.d.ts +0 -61
- package/dist/src/rules/user.mapper.js +0 -160
- package/dist/src/rules/utils/slug.d.ts +0 -22
- 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] =
|
|
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
|
|
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)
|
package/dist/src/types.d.ts
CHANGED
|
@@ -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
|
-
|
|
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: [
|
|
45
|
+
actions: [],
|
|
46
46
|
lastMessage: a.lastMessage || '',
|
|
47
47
|
usage: {
|
|
48
48
|
prompt: (a.usage?.prompt || 0) + (b.usage?.prompt || 0),
|
package/dist/src/usecase.d.ts
CHANGED
|
@@ -1,4 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
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
|
}>;
|
package/dist/src/usecase.js
CHANGED
|
@@ -1,44 +1,36 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
const princing_openai_1 = require("./princing.openai");
|
|
3
|
+
exports.llmExtractUserQueries = llmExtractUserQueries;
|
|
5
4
|
const prompts_1 = require("./prompts");
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
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
|
-
//
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
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
|
|
35
|
-
|
|
36
|
-
|
|
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
|
}
|
package/dist/src/utils.d.ts
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import { ParsedFunctionToolCall } from "openai/resources/beta/chat/completions";
|
|
2
2
|
import { AgentConfig, AgenticContext } from "./types";
|
|
3
|
-
|
|
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
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
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
|
-
|
|
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
|
|
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 ? '(
|
|
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.
|
|
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 user
|
|
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,
|
|
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
|
-
|
|
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
|
-
|
|
202
|
-
|
|
193
|
+
content: '', // ✅ Transfert silencieux
|
|
194
|
+
did_transfer: true
|
|
203
195
|
};
|
|
204
196
|
}
|
|
205
197
|
else {
|
|
206
|
-
console.log("
|
|
198
|
+
console.log(`❌L'agent destination "${destinationAgentName}" n'a pas été trouvé.`);
|
|
207
199
|
return {
|
|
208
|
-
feedback:
|
|
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
|
-
}
|