agentic-api 1.0.1
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/README.md +198 -0
- package/dist/src/agents/authentication.d.ts +6 -0
- package/dist/src/agents/authentication.js +216 -0
- package/dist/src/agents/digestor.d.ts +7 -0
- package/dist/src/agents/digestor.js +60 -0
- package/dist/src/agents/memory.d.ts +0 -0
- package/dist/src/agents/memory.js +1 -0
- package/dist/src/agents/prompts.d.ts +7 -0
- package/dist/src/agents/prompts.js +302 -0
- package/dist/src/agents/semantic.d.ts +4 -0
- package/dist/src/agents/semantic.js +20 -0
- package/dist/src/agents/simpleExample.d.ts +3 -0
- package/dist/src/agents/simpleExample.js +38 -0
- package/dist/src/agents/system-review.d.ts +5 -0
- package/dist/src/agents/system-review.js +181 -0
- package/dist/src/agents/system.d.ts +4 -0
- package/dist/src/agents/system.js +21 -0
- package/dist/src/agents/systemReview.d.ts +4 -0
- package/dist/src/agents/systemReview.js +22 -0
- package/dist/src/execute.d.ts +42 -0
- package/dist/src/execute.js +289 -0
- package/dist/src/index.d.ts +11 -0
- package/dist/src/index.js +32 -0
- package/dist/src/princing.openai.d.ts +4 -0
- package/dist/src/princing.openai.js +49 -0
- package/dist/src/prompts.d.ts +5 -0
- package/dist/src/prompts.js +136 -0
- package/dist/src/scrapper.d.ts +54 -0
- package/dist/src/scrapper.js +294 -0
- package/dist/src/types.d.ts +126 -0
- package/dist/src/types.js +93 -0
- package/dist/src/utils.d.ts +27 -0
- package/dist/src/utils.js +288 -0
- package/package.json +45 -0
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.slug = exports.openaiInstance = void 0;
|
|
4
|
+
exports.injectTransferTools = injectTransferTools;
|
|
5
|
+
exports.handleTransferCall = handleTransferCall;
|
|
6
|
+
exports.callForSystemReview = callForSystemReview;
|
|
7
|
+
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;
|
|
14
|
+
}
|
|
15
|
+
if (!_openaiInstance) {
|
|
16
|
+
throw new Error('OpenAI instance has not been initialized');
|
|
17
|
+
}
|
|
18
|
+
return _openaiInstance;
|
|
19
|
+
};
|
|
20
|
+
exports.openaiInstance = openaiInstance;
|
|
21
|
+
const slug = (text) => {
|
|
22
|
+
return text.toLowerCase().replace(/ /g, '-').replace(/[^a-z0-9àâçéèêëîïôûù-]+/g, '').replace(/-{2,}/g, '-');
|
|
23
|
+
};
|
|
24
|
+
exports.slug = slug;
|
|
25
|
+
/**
|
|
26
|
+
* This defines and adds "transferAgents" tool dynamically based on the specified downstreamAgents on each agent.
|
|
27
|
+
*/
|
|
28
|
+
function injectTransferTools(agentDefs) {
|
|
29
|
+
// Iterate over each agent definition
|
|
30
|
+
agentDefs.forEach((agentDef) => {
|
|
31
|
+
if (agentDef.ready) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
const downstreamAgents = agentDef.downstreamAgents || [];
|
|
35
|
+
//
|
|
36
|
+
// Add the think tool if maxSteps is set
|
|
37
|
+
// https://www.aihero.dev/implementing-anthropics-think-tool-in-typescript
|
|
38
|
+
if (agentDef.maxSteps && agentDef.maxSteps > 0) {
|
|
39
|
+
const description = `
|
|
40
|
+
Use the tool as a helper to think about something with a plan of multiple steps.
|
|
41
|
+
It will not obtain new information or change the database, but just append the thought to the log.
|
|
42
|
+
Use it when complex reasoning or some cache memory is needed.
|
|
43
|
+
To avoid infinite thinking, the tool is limited to ${agentDef.maxSteps} calls.
|
|
44
|
+
|
|
45
|
+
It takes two arguments:
|
|
46
|
+
- thought (str): A thought to think about.
|
|
47
|
+
- step (int): The incremented step number that constrains the global thinking with a limitation of ${agentDef.maxSteps} calls.
|
|
48
|
+
`;
|
|
49
|
+
const think = {
|
|
50
|
+
type: "function",
|
|
51
|
+
function: {
|
|
52
|
+
name: "thinking",
|
|
53
|
+
description,
|
|
54
|
+
strict: true,
|
|
55
|
+
parameters: {
|
|
56
|
+
type: "object",
|
|
57
|
+
properties: {
|
|
58
|
+
justification: {
|
|
59
|
+
type: "string",
|
|
60
|
+
description: "The reasoning why this thinking is needed.",
|
|
61
|
+
},
|
|
62
|
+
thought: {
|
|
63
|
+
type: "string",
|
|
64
|
+
description: "A thought to think about.",
|
|
65
|
+
},
|
|
66
|
+
step: {
|
|
67
|
+
type: "number",
|
|
68
|
+
description: "The incremented step number that constrains the global thinking.",
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
required: ["justification", "thought", "step"],
|
|
72
|
+
additionalProperties: false,
|
|
73
|
+
},
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
// Ensure the agent has a tools array
|
|
77
|
+
if (!agentDef.tools) {
|
|
78
|
+
agentDef.tools = [];
|
|
79
|
+
}
|
|
80
|
+
console.log('--- DBG addTools', agentDef.name, 'with think step', agentDef.maxSteps);
|
|
81
|
+
// Add the newly created tool to the current agent's tools
|
|
82
|
+
agentDef.tools.push(think);
|
|
83
|
+
}
|
|
84
|
+
// Only proceed if there are downstream agents
|
|
85
|
+
if (downstreamAgents.length > 0) {
|
|
86
|
+
// Build a list of downstream agents and their descriptions for the prompt
|
|
87
|
+
const availableAgentsList = downstreamAgents
|
|
88
|
+
.map((dAgent) => `- ${dAgent.name}: ${dAgent.publicDescription ?? "No description"} ${dAgent.human ? '(human agent, less specialized)' : ''}`)
|
|
89
|
+
.join("\n");
|
|
90
|
+
// Create the transfer_agent tool specific to this agent
|
|
91
|
+
const transferAgentTool = {
|
|
92
|
+
type: "function",
|
|
93
|
+
function: {
|
|
94
|
+
name: "transferAgents",
|
|
95
|
+
description: `${prompts_1.transferAgentPrompt.replace('__AGENT_NAME__', agentDef.name)}
|
|
96
|
+
${availableAgentsList}
|
|
97
|
+
`,
|
|
98
|
+
parameters: {
|
|
99
|
+
type: "object",
|
|
100
|
+
properties: {
|
|
101
|
+
rationale_for_transfer: {
|
|
102
|
+
type: "string",
|
|
103
|
+
description: "The reasoning why this transfer is needed.",
|
|
104
|
+
},
|
|
105
|
+
conversation_context: {
|
|
106
|
+
type: "string",
|
|
107
|
+
description: "Relevant context from the conversation that will help the recipient perform the correct action.",
|
|
108
|
+
},
|
|
109
|
+
destination_agent: {
|
|
110
|
+
type: "string",
|
|
111
|
+
description: "The more specialized destination_agent that should handle the user’s intended request.",
|
|
112
|
+
enum: downstreamAgents.map((dAgent) => dAgent.name),
|
|
113
|
+
},
|
|
114
|
+
confidence: {
|
|
115
|
+
type: "number",
|
|
116
|
+
description: "The confidence that the transfer to a more appropriate agent is needed."
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
required: [
|
|
120
|
+
"rationale_for_transfer",
|
|
121
|
+
"conversation_context",
|
|
122
|
+
"destination_agent",
|
|
123
|
+
"confidence",
|
|
124
|
+
],
|
|
125
|
+
additionalProperties: false,
|
|
126
|
+
},
|
|
127
|
+
strict: true,
|
|
128
|
+
},
|
|
129
|
+
};
|
|
130
|
+
// Ensure the agent has a tools array
|
|
131
|
+
if (!agentDef.tools) {
|
|
132
|
+
agentDef.tools = [];
|
|
133
|
+
}
|
|
134
|
+
// Add the newly created tool to the current agent's tools
|
|
135
|
+
agentDef.tools.push(transferAgentTool);
|
|
136
|
+
// console.log('--- DBG injectTransferTools',agentDef.name,'with new transfer',JSON.stringify(transferAgentTool.function.parameters,null,2 ));
|
|
137
|
+
}
|
|
138
|
+
// so .stringify doesn't break with circular dependencies
|
|
139
|
+
agentDef.downstreamAgents = agentDef.downstreamAgents?.map(({ name, publicDescription, human }) => ({
|
|
140
|
+
name,
|
|
141
|
+
publicDescription,
|
|
142
|
+
human
|
|
143
|
+
}));
|
|
144
|
+
agentDef.ready = true;
|
|
145
|
+
});
|
|
146
|
+
return agentDefs;
|
|
147
|
+
}
|
|
148
|
+
//
|
|
149
|
+
// Fonction pour gérer un appel de fonction retourné par OpenAI
|
|
150
|
+
// le contexte est un objet qui contient des informations supplémentaires de session
|
|
151
|
+
async function handleTransferCall(memory, functionCallParams, session) {
|
|
152
|
+
const { agents } = memory;
|
|
153
|
+
const currentAgentName = memory.currentAgent?.name;
|
|
154
|
+
const args = JSON.parse(functionCallParams?.function?.arguments || '{}');
|
|
155
|
+
// console.log("↩️ Appel de fonction à gérer :",currentAgent?.name,'->', functionCallParams.function.name,'::',args);
|
|
156
|
+
if (functionCallParams.function.name === "transferAgents") {
|
|
157
|
+
if (args.confidence < 0.7) {
|
|
158
|
+
return {
|
|
159
|
+
content: "Le transfert n'est pas nécessaire, tu DOIS répondre directement",
|
|
160
|
+
feedback: args.rationale_for_transfer,
|
|
161
|
+
did_transfer: false,
|
|
162
|
+
name: functionCallParams.function.name
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
const destinationAgentName = args.destination_agent;
|
|
166
|
+
console.log(`🤖 Transfert de l'agent "${currentAgentName}" vers "${destinationAgentName}" (${args?.confidence})`, '::', args?.rationale_for_transfer);
|
|
167
|
+
// For debug, we don't want to transfer to the same agent
|
|
168
|
+
if (currentAgentName === destinationAgentName) {
|
|
169
|
+
console.log("❌ Le transfert sur moi-même n'est pas nécessaire", destinationAgentName, args);
|
|
170
|
+
memory.messages.slice(1).forEach(m => {
|
|
171
|
+
process.stdout.write(`-- DBG ---> 🤖 ${m.role}: ${m.content}\n`);
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
//
|
|
175
|
+
// agent transfer to the destination agent
|
|
176
|
+
const destinationAgent = agents.find((agent) => agent.name === destinationAgentName);
|
|
177
|
+
if (destinationAgent) {
|
|
178
|
+
//console.log(`🤖 Agent "${destinationAgent.name}" en préparation`);
|
|
179
|
+
memory.currentAgent = destinationAgent;
|
|
180
|
+
return {
|
|
181
|
+
feedback: args.rationale_for_transfer,
|
|
182
|
+
destination_agent: destinationAgentName,
|
|
183
|
+
source_agent: currentAgentName,
|
|
184
|
+
did_transfer: true,
|
|
185
|
+
name: functionCallParams.function.name
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
console.log("❌ Agent non trouvé !");
|
|
190
|
+
return {
|
|
191
|
+
feedback: "L'agent destination n'a pas été trouvé.",
|
|
192
|
+
did_transfer: false,
|
|
193
|
+
name: functionCallParams.function.name
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
if (functionCallParams.function.name === "thinking") {
|
|
198
|
+
const { justification, thought, step } = args;
|
|
199
|
+
console.log('🤖', memory.currentAgent?.name, '->', functionCallParams.function.name, '::', thought, '(step', step, ')');
|
|
200
|
+
return {
|
|
201
|
+
feedback: justification,
|
|
202
|
+
content: `Pour l'étape ${step}, j'ai pensé à "${thought}"`,
|
|
203
|
+
name: functionCallParams.function.name,
|
|
204
|
+
usage: 0
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
//
|
|
208
|
+
// looking on agents tool logic
|
|
209
|
+
const agent = memory.currentAgent;
|
|
210
|
+
if (agent?.toolLogic && agent.toolLogic[functionCallParams.function.name]) {
|
|
211
|
+
const { content, usage } = await agent.toolLogic[functionCallParams.function.name](args, session);
|
|
212
|
+
console.log('🤖', agent.name, '->', functionCallParams.function.name, '::usage', usage);
|
|
213
|
+
return {
|
|
214
|
+
content,
|
|
215
|
+
name: functionCallParams.function.name,
|
|
216
|
+
usage
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
else {
|
|
220
|
+
// whit thinking, we hask the agent to restart the conversation
|
|
221
|
+
// console.log('🤖',agent.name,'->',agent.tools[0]);
|
|
222
|
+
console.log("❌ Cette fonction n'existe pas !", agent.name, functionCallParams.function.name);
|
|
223
|
+
return {
|
|
224
|
+
feedback: `Humm, cette fonction "${functionCallParams.function.name}" n'existe pas!`,
|
|
225
|
+
name: functionCallParams.function.name,
|
|
226
|
+
content: `Cette fonction "${functionCallParams.function.name}" n'existe pas, tu ne dois plus l'appeler et TU DOIS répondre à la question.`
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Calls the system review agent to analyze a prompt
|
|
232
|
+
*
|
|
233
|
+
* This function sends a prompt to the system review agent and returns its analysis.
|
|
234
|
+
* The system review agent evaluates prompts based on various criteria like clarity,
|
|
235
|
+
* identity, scope, decision logic, etc.
|
|
236
|
+
*
|
|
237
|
+
* @param {string} prompt - The prompt text to be analyzed by the system review agent
|
|
238
|
+
* @param {Object} params - Parameters for the API call
|
|
239
|
+
* @param {Object} params.openai - The OpenAI client instance
|
|
240
|
+
* @param {Object} params.defaultOptions - Default options to be merged with agent model options
|
|
241
|
+
* @returns {Promise<string>} The analysis response from the system review agent
|
|
242
|
+
*/
|
|
243
|
+
async function callForSystemReview(prompt, params) {
|
|
244
|
+
const { openai, defaultOptions } = params;
|
|
245
|
+
const agent = system_1.system;
|
|
246
|
+
const options = Object.assign({}, agent.model, defaultOptions || {});
|
|
247
|
+
const jsonOptions = `
|
|
248
|
+
- L'option JSON a été activée, tu dois respecter le format brut suivant \`
|
|
249
|
+
{
|
|
250
|
+
directives: [
|
|
251
|
+
{"directive": "...","criteria": [{"criterion": "...","score": "...","comment": "..."}]},
|
|
252
|
+
...
|
|
253
|
+
]
|
|
254
|
+
}
|
|
255
|
+
\``;
|
|
256
|
+
//
|
|
257
|
+
// add the initial agent to his memory
|
|
258
|
+
// Handle two-shot prompting: if instructions is an array, use the first part as a system message
|
|
259
|
+
const instructions = agent.instructions;
|
|
260
|
+
options.messages = [
|
|
261
|
+
{ role: "system", content: instructions }
|
|
262
|
+
];
|
|
263
|
+
if (options.response_format?.type == "json_object") {
|
|
264
|
+
options.messages.push({ role: "user", content: jsonOptions });
|
|
265
|
+
}
|
|
266
|
+
options.messages.push({ role: "user", content: `tu dois analyser toutes les directives:\n ${prompt}` });
|
|
267
|
+
let thinking = 1;
|
|
268
|
+
//
|
|
269
|
+
// loop until the agent has finished thinking
|
|
270
|
+
do {
|
|
271
|
+
const response = await openai.chat.completions.create(options);
|
|
272
|
+
const cost = (0, princing_openai_1.calculateCost)(options.model, response.usage);
|
|
273
|
+
if (options.response_format?.type == "json_object") {
|
|
274
|
+
const content = JSON.parse(response.choices[0].message.content || '{}');
|
|
275
|
+
return { content, cost };
|
|
276
|
+
}
|
|
277
|
+
// Handle two-shot prompting: if instructions is an array, send the second part as a user message
|
|
278
|
+
// This allows for more complex agent behavior by providing additional context or instructions
|
|
279
|
+
// after the initial response, similar to chain-of-thought prompting
|
|
280
|
+
if (!Array.isArray(agent.instructions) || thinking >= agent.instructions.length) {
|
|
281
|
+
const content = response.choices[0].message.content;
|
|
282
|
+
return { content, cost };
|
|
283
|
+
}
|
|
284
|
+
const instructions = agent.instructions[thinking];
|
|
285
|
+
options.messages.push({ role: "user", content: instructions });
|
|
286
|
+
thinking++;
|
|
287
|
+
} while (true);
|
|
288
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "agentic-api",
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"description": "API pour l'orchestration d'agents intelligents avec séquences et escalades automatiques",
|
|
5
|
+
"main": "dist/src/index.js",
|
|
6
|
+
"types": "dist/src/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist/src"
|
|
9
|
+
],
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc",
|
|
12
|
+
"test": "jest",
|
|
13
|
+
"lint": "eslint 'src/**/*.ts'",
|
|
14
|
+
"prepublishOnly": "npm run build",
|
|
15
|
+
"extract:pdf": "texttopdf "
|
|
16
|
+
},
|
|
17
|
+
"optionalDependencies": {
|
|
18
|
+
"python3": ">=3.5"
|
|
19
|
+
},
|
|
20
|
+
"dependencies": {
|
|
21
|
+
"@mozilla/readability": "^0.6.0",
|
|
22
|
+
"dotenv": "^16.4.7",
|
|
23
|
+
"hnswlib-node": "^3.0.0",
|
|
24
|
+
"jsdom": "^26.0.0",
|
|
25
|
+
"openai": "^4.89.0"
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"@types/jest": "^29.5.14",
|
|
29
|
+
"@types/jsdom": "^21.1.7",
|
|
30
|
+
"@types/node": "^22.13.2",
|
|
31
|
+
"eslint": "^8.56.0",
|
|
32
|
+
"jest": "^29.7.0",
|
|
33
|
+
"ts-jest": "^29.2.5",
|
|
34
|
+
"typescript": "^5.7.3"
|
|
35
|
+
},
|
|
36
|
+
"keywords": [
|
|
37
|
+
"agent",
|
|
38
|
+
"llm",
|
|
39
|
+
"openai",
|
|
40
|
+
"rag",
|
|
41
|
+
"ai"
|
|
42
|
+
],
|
|
43
|
+
"author": "Olivier Evalet",
|
|
44
|
+
"license": "MIT"
|
|
45
|
+
}
|