agentic-api 2.0.646 → 2.0.885
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/prompts.d.ts +2 -3
- package/dist/src/agents/prompts.js +21 -118
- package/dist/src/agents/reducer.loaders.d.ts +103 -1
- package/dist/src/agents/reducer.loaders.js +164 -2
- package/dist/src/agents/reducer.types.d.ts +34 -3
- package/dist/src/agents/simulator.d.ts +32 -2
- package/dist/src/agents/simulator.executor.d.ts +15 -5
- package/dist/src/agents/simulator.executor.js +134 -67
- package/dist/src/agents/simulator.js +251 -8
- package/dist/src/agents/simulator.prompts.d.ts +55 -10
- package/dist/src/agents/simulator.prompts.js +305 -61
- package/dist/src/agents/simulator.types.d.ts +62 -1
- package/dist/src/agents/simulator.types.js +5 -0
- package/dist/src/agents/subagent.d.ts +128 -0
- package/dist/src/agents/subagent.js +231 -0
- package/dist/src/agents/worker.executor.d.ts +48 -0
- package/dist/src/agents/worker.executor.js +152 -0
- package/dist/src/execute/helpers.d.ts +3 -0
- package/dist/src/execute/helpers.js +222 -16
- package/dist/src/execute/responses.js +81 -55
- package/dist/src/execute/shared.d.ts +5 -0
- package/dist/src/execute/shared.js +27 -0
- package/dist/src/index.d.ts +2 -1
- package/dist/src/index.js +3 -1
- package/dist/src/llm/openai.js +8 -1
- package/dist/src/llm/pricing.js +2 -0
- package/dist/src/llm/xai.js +11 -6
- package/dist/src/prompts.d.ts +14 -0
- package/dist/src/prompts.js +41 -1
- package/dist/src/rag/rag.manager.d.ts +18 -3
- package/dist/src/rag/rag.manager.js +114 -12
- package/dist/src/rag/types.d.ts +3 -1
- package/dist/src/rules/git/git.e2e.helper.js +51 -4
- package/dist/src/rules/git/git.health.js +89 -56
- package/dist/src/rules/git/index.d.ts +2 -2
- package/dist/src/rules/git/index.js +22 -5
- package/dist/src/rules/git/repo.d.ts +64 -6
- package/dist/src/rules/git/repo.js +572 -141
- package/dist/src/rules/git/repo.pr.d.ts +11 -18
- package/dist/src/rules/git/repo.pr.js +82 -94
- package/dist/src/rules/git/repo.tools.d.ts +5 -0
- package/dist/src/rules/git/repo.tools.js +6 -1
- package/dist/src/rules/types.d.ts +0 -2
- package/dist/src/rules/utils.matter.js +1 -5
- package/dist/src/scrapper.d.ts +138 -25
- package/dist/src/scrapper.js +538 -160
- package/dist/src/stategraph/stategraph.d.ts +6 -2
- package/dist/src/stategraph/stategraph.js +21 -6
- package/dist/src/stategraph/types.d.ts +14 -6
- package/dist/src/types.d.ts +22 -0
- package/dist/src/utils.d.ts +24 -0
- package/dist/src/utils.js +84 -86
- package/package.json +3 -2
- package/dist/src/agents/semantic.d.ts +0 -4
- package/dist/src/agents/semantic.js +0 -19
- package/dist/src/execute/legacy.d.ts +0 -46
- package/dist/src/execute/legacy.js +0 -460
- package/dist/src/pricing.llm.d.ts +0 -5
- package/dist/src/pricing.llm.js +0 -14
|
@@ -1,10 +1,62 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
2
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
36
|
exports.accumulateUsageTokens = accumulateUsageTokens;
|
|
4
37
|
exports.stepsToActions = stepsToActions;
|
|
38
|
+
exports.handleSubAgentCall = handleSubAgentCall;
|
|
5
39
|
exports.batchProcessToolCalls = batchProcessToolCalls;
|
|
40
|
+
const stream_1 = require("stream");
|
|
6
41
|
const pricing_1 = require("../llm/pricing");
|
|
42
|
+
const subagent_1 = require("../agents/subagent");
|
|
7
43
|
const utils_1 = require("../utils");
|
|
44
|
+
const responses_1 = require("./responses");
|
|
45
|
+
//
|
|
46
|
+
// Stdout filtré pour les sub-agents : ne laisse passer que les <step> (sendFeedback)
|
|
47
|
+
// et supprime le texte brut du LLM (qui ne doit pas être streamé au user final).
|
|
48
|
+
// sendFeedback écrit toujours `\n<step>JSON</step>\n` en un seul write.
|
|
49
|
+
function createFeedbackOnlyStdout(target) {
|
|
50
|
+
return new stream_1.Writable({
|
|
51
|
+
write(chunk, _enc, cb) {
|
|
52
|
+
const str = chunk.toString();
|
|
53
|
+
if (str.includes('<step>')) {
|
|
54
|
+
target.write(chunk);
|
|
55
|
+
}
|
|
56
|
+
cb();
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
}
|
|
8
60
|
/**
|
|
9
61
|
* OPTIM: Accumule l'usage des tokens et met à jour stateGraph + discussion.usage
|
|
10
62
|
*
|
|
@@ -45,10 +97,154 @@ function accumulateUsageTokens(stateGraph, discussion, agentName, model, usage)
|
|
|
45
97
|
function stepsToActions(stateGraph, agentName) {
|
|
46
98
|
return stateGraph.steps(agentName).map(step => ({
|
|
47
99
|
action: step.tool,
|
|
48
|
-
content: step.
|
|
100
|
+
content: step.reason,
|
|
49
101
|
feedback: step.reason
|
|
50
102
|
}));
|
|
51
103
|
}
|
|
104
|
+
/**
|
|
105
|
+
* Gère l'exécution d'un sub-agent via la convention `subAgent<Name>`.
|
|
106
|
+
*
|
|
107
|
+
* Clé de session : `{parentDiscussionId}_{toolName}` (ex: `f3a9b1_subAgentPRMaster`).
|
|
108
|
+
* - Isole la session par (discussion parente × tool) → pas de fuite entre users/conversations.
|
|
109
|
+
* - useSession=true → session persistante : le sub-agent accumule le contexte entre appels.
|
|
110
|
+
* - useSession=false → éphémère : clearDiscussion avant exec, repart d'un slate vide.
|
|
111
|
+
*
|
|
112
|
+
* Le sub-agent est cloné avec `name = sessionKey` pour que executeAgentSet utilise
|
|
113
|
+
* la bonne clé dans le stateGraph partagé sans écraser la discussion `<Name>` parente.
|
|
114
|
+
*/
|
|
115
|
+
function buildSubAgentFallbackResult(toolName, fallbackMessage, feedback, status = 'error') {
|
|
116
|
+
const result = {
|
|
117
|
+
status,
|
|
118
|
+
items: fallbackMessage ? [fallbackMessage] : [],
|
|
119
|
+
meta: {
|
|
120
|
+
resolved: [],
|
|
121
|
+
notFound: [],
|
|
122
|
+
knowledge_found: 'no'
|
|
123
|
+
},
|
|
124
|
+
control: {
|
|
125
|
+
can_retry: false
|
|
126
|
+
},
|
|
127
|
+
content: '',
|
|
128
|
+
name: toolName,
|
|
129
|
+
feedback
|
|
130
|
+
};
|
|
131
|
+
result.content = JSON.stringify({
|
|
132
|
+
status: result.status,
|
|
133
|
+
items: result.items,
|
|
134
|
+
meta: result.meta,
|
|
135
|
+
control: result.control
|
|
136
|
+
});
|
|
137
|
+
return result;
|
|
138
|
+
}
|
|
139
|
+
async function handleSubAgentCall(stateGraph, agents, functionCallParams, context) {
|
|
140
|
+
const toolName = functionCallParams.function.name; // ex: 'subAgentPRMaster'
|
|
141
|
+
const args = JSON.parse(functionCallParams?.function?.arguments || '{}');
|
|
142
|
+
const useSession = true;
|
|
143
|
+
//
|
|
144
|
+
// Composer la mission — supporte ancien triplet (subject/context/expected_result) et nouveau (query/context/goal)
|
|
145
|
+
const { subAgentComposeMission } = await Promise.resolve().then(() => __importStar(require('../agents/subagent')));
|
|
146
|
+
const mission = subAgentComposeMission(args);
|
|
147
|
+
//
|
|
148
|
+
// Rétro-compat : confidence seuil (ancien format)
|
|
149
|
+
if (args.confidence != null && args.confidence < 0.5) {
|
|
150
|
+
return buildSubAgentFallbackResult(toolName, `La délégation n'est pas nécessaire (confidence: ${args.confidence}), réponds directement.`, args.rationale_for_agent || args.query || '', 'empty');
|
|
151
|
+
}
|
|
152
|
+
//
|
|
153
|
+
// Rationale pour logging/feedback (ancien: rationale_for_agent, nouveau: query)
|
|
154
|
+
const rationale = args.rationale_for_agent || args.query || '';
|
|
155
|
+
//
|
|
156
|
+
// Convention subAgent<Name> → <Name> (ex: subAgentPRMaster → PRMaster)
|
|
157
|
+
const subAgentName = toolName.replace(/^subAgent([A-Z])/, (_, c) => c);
|
|
158
|
+
const subAgent = agents.find(a => a.name === subAgentName);
|
|
159
|
+
if (!subAgent) {
|
|
160
|
+
console.log(`❌ Sub-agent "${subAgentName}" introuvable.`);
|
|
161
|
+
return buildSubAgentFallbackResult(toolName, `❌ Sub-agent "${subAgentName}" introuvable.`, rationale);
|
|
162
|
+
}
|
|
163
|
+
//
|
|
164
|
+
// Clé de session scoped : {parentDiscussionId}_{toolName}
|
|
165
|
+
// - Isole la discussion du sub-agent par (user × conversation × tool)
|
|
166
|
+
// - context.discussionRootAgent est fixé avant batchProcessToolCalls (responses.ts)
|
|
167
|
+
// - Le save/restore ci-dessous garantit que l'UUID du root agent reste stable
|
|
168
|
+
// même si executeAgentSet le mute en interne.
|
|
169
|
+
const discussionRootAgent = context.discussionRootAgent;
|
|
170
|
+
const parentDiscussion = stateGraph.createOrRestore(discussionRootAgent);
|
|
171
|
+
const sessionKey = `${parentDiscussion.id}_${toolName}`;
|
|
172
|
+
// useSession=false → éphémère : vider la discussion avant exec
|
|
173
|
+
if (!useSession) {
|
|
174
|
+
stateGraph.clearDiscussion(sessionKey);
|
|
175
|
+
}
|
|
176
|
+
const subDiscussion = stateGraph.createOrRestore(sessionKey);
|
|
177
|
+
//
|
|
178
|
+
// Clone l'agent avec name = sessionKey pour que executeAgentSet utilise
|
|
179
|
+
// la bonne clé dans le stateGraph partagé (pas de collision avec PRMaster).
|
|
180
|
+
// subAgents: [] — empêche la découverte récursive de subAgents dans l'exécution isolée.
|
|
181
|
+
// tools snapshot — isole les tools de l'original pour éviter toute propagation de mutation.
|
|
182
|
+
const isolatedAgent = {
|
|
183
|
+
...subAgent,
|
|
184
|
+
name: sessionKey,
|
|
185
|
+
subAgents: [],
|
|
186
|
+
tools: [...(subAgent.tools || [])].filter(t => !t.function.name.startsWith('subAgent')),
|
|
187
|
+
};
|
|
188
|
+
//
|
|
189
|
+
// Save/restore : executeAgentSet mute context.discussionRootAgent = sessionKey.
|
|
190
|
+
// Sans restore, un 2e appel subAgent séquentiel lirait la valeur mutée et créerait
|
|
191
|
+
// une nouvelle discussion au lieu de réutiliser celle du root agent.
|
|
192
|
+
//
|
|
193
|
+
// feedbackOnlyStdout : ne streame que les <step> (sendFeedback) vers l'utilisateur.
|
|
194
|
+
// Le texte LLM du sub-agent est supprimé — seul le parent reformule la réponse finale.
|
|
195
|
+
const feedbackStdout = createFeedbackOnlyStdout(context.stdout);
|
|
196
|
+
const outputSchema = subAgent.outputSchema ?? subagent_1.SUBAGENT_OUTPUT_SCHEMA;
|
|
197
|
+
const subAgentStartMs = Date.now();
|
|
198
|
+
const savedDiscussionRootAgent = context.discussionRootAgent;
|
|
199
|
+
const result = await (0, responses_1.executeAgentSet)([isolatedAgent], context, {
|
|
200
|
+
query: mission,
|
|
201
|
+
home: sessionKey,
|
|
202
|
+
schema: outputSchema,
|
|
203
|
+
stdout: feedbackStdout,
|
|
204
|
+
verbose: true
|
|
205
|
+
});
|
|
206
|
+
context.discussionRootAgent = savedDiscussionRootAgent;
|
|
207
|
+
// console.log('🔍 SubAgentCall', result.lastMessage);
|
|
208
|
+
//
|
|
209
|
+
// Trace dans le context trail de la discussion parente
|
|
210
|
+
stateGraph.addStep(discussionRootAgent, {
|
|
211
|
+
tool: toolName,
|
|
212
|
+
reason: `${rationale} — ${mission}`
|
|
213
|
+
});
|
|
214
|
+
//
|
|
215
|
+
// Diagnostic subAgent : taille du résultat + temps d'exécution
|
|
216
|
+
const elapsedMs = Date.now() - subAgentStartMs;
|
|
217
|
+
const msgLength = result.lastMessage?.length || 0;
|
|
218
|
+
console.log(`🔀 SubAgent "${subAgentName}" prompt("${mission}") — message("${msgLength} chars"), ${elapsedMs}ms, usage: ${result.usage.prompt}:${result.usage.completion} tokens\n`, `🔀 SubAgent clé "${sessionKey}" (${subDiscussion.messages.length} msgs)\n`); // `🔀 SubAgent result: ${result.lastMessage}`
|
|
219
|
+
const rawContent = result.lastMessage || result.error || `❌ Sub-agent "${subAgentName}" n'a pas retourné de résultat.`;
|
|
220
|
+
const parsedOutput = (0, subagent_1.parseSubAgentOutputContent)(rawContent);
|
|
221
|
+
if (!parsedOutput) {
|
|
222
|
+
return buildSubAgentFallbackResult(toolName, rawContent, rationale);
|
|
223
|
+
}
|
|
224
|
+
const content = JSON.stringify(parsedOutput);
|
|
225
|
+
return {
|
|
226
|
+
...parsedOutput,
|
|
227
|
+
//
|
|
228
|
+
// content = texte plain pour function_call_output (lu par batchProcessToolCalls)
|
|
229
|
+
content,
|
|
230
|
+
name: toolName,
|
|
231
|
+
feedback: rationale
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Dispatch un tool call vers le bon handler (subAgent* ou toolLogic).
|
|
236
|
+
* Priorité : handleSubAgentCall > handleToolLogicCall.
|
|
237
|
+
*
|
|
238
|
+
* Utilisé dans Promise.all — ne traite PAS transferAgents (court-circuité en amont).
|
|
239
|
+
* context.discussionRootAgent est utilisé par handleSubAgentCall pour la clé de session.
|
|
240
|
+
*/
|
|
241
|
+
async function dispatchToolCall(stateGraph, currentAgentRef, agents, toolCall, context) {
|
|
242
|
+
const toolName = toolCall.function.name;
|
|
243
|
+
if (toolName.startsWith('subAgent')) {
|
|
244
|
+
return handleSubAgentCall(stateGraph, agents, toolCall, context);
|
|
245
|
+
}
|
|
246
|
+
return (0, utils_1.handleToolLogicCall)(currentAgentRef, agents, toolCall, context);
|
|
247
|
+
}
|
|
52
248
|
/**
|
|
53
249
|
* OPTIM: Traite tous les tool calls en batch et retourne les résultats
|
|
54
250
|
*
|
|
@@ -102,38 +298,48 @@ async function batchProcessToolCalls(toolCalls, agents, stateGraph, agentName, c
|
|
|
102
298
|
// ✅ Préparer les tool_outputs pour submitToolOutputs
|
|
103
299
|
const toolOutputs = [];
|
|
104
300
|
//
|
|
105
|
-
//
|
|
106
|
-
|
|
107
|
-
|
|
301
|
+
// ✅ Court-circuit : transferAgents traité séquentiellement en priorité absolue.
|
|
302
|
+
// Un handoff modifie currentAgentRef (effet de bord mutable) — incompatible Promise.all.
|
|
303
|
+
const transferCall = parsedCalls.find(tc => tc.function.name === 'transferAgents');
|
|
304
|
+
if (transferCall) {
|
|
305
|
+
const result = await (0, utils_1.handleTransferCall)(discussion, currentAgentRef, agents, transferCall, context);
|
|
108
306
|
results.push(result);
|
|
109
|
-
// ✅ Détecter les transfers
|
|
110
307
|
if (result.did_transfer && result.destination_agent) {
|
|
111
308
|
hasTransfer = true;
|
|
112
309
|
transferAgentName = result.destination_agent;
|
|
113
310
|
}
|
|
311
|
+
if (result.content || result.did_transfer || result.rawResult) {
|
|
312
|
+
needsFollowUp = true;
|
|
313
|
+
toolOutputs.push({
|
|
314
|
+
call_id: transferCall.id,
|
|
315
|
+
output: result.content || JSON.stringify(result.rawResult || result)
|
|
316
|
+
});
|
|
317
|
+
}
|
|
318
|
+
return { results, needsFollowUp, parsedCalls, transferAgentName, hasTransfer, toolOutputs };
|
|
319
|
+
}
|
|
320
|
+
//
|
|
321
|
+
// ✅ Tous les autres tool calls (subAgent*, toolLogic, thinking) : exécution parallèle.
|
|
322
|
+
// Indépendants entre eux, pas d'effet de bord sur currentAgentRef.
|
|
323
|
+
const parallelCalls = parsedCalls.map(toolCall => dispatchToolCall(stateGraph, currentAgentRef, agents, toolCall, context)
|
|
324
|
+
.then(result => ({ toolCall, result })));
|
|
325
|
+
const settled = await Promise.all(parallelCalls);
|
|
326
|
+
for (const { toolCall, result } of settled) {
|
|
327
|
+
results.push(result);
|
|
114
328
|
//
|
|
115
|
-
// Accumuler les messages pour le follow-up
|
|
116
329
|
// ✅ IMPORTANT: Toujours ajouter l'output même si content est undefined
|
|
117
330
|
// Car un ToolContractOutput peut ne pas avoir de content mais avoir rawResult
|
|
118
|
-
if (result.content || result.
|
|
331
|
+
if (result.content || result.rawResult) {
|
|
119
332
|
needsFollowUp = true;
|
|
120
|
-
// ✅ Préparer les outputs pour function_call_output
|
|
121
|
-
// Si content existe, l'utiliser (texte formaté)
|
|
122
|
-
// Sinon, sérialiser rawResult si présent (ToolContractOutput), sinon result complet
|
|
123
333
|
toolOutputs.push({
|
|
124
334
|
call_id: toolCall.id,
|
|
125
|
-
// ⚠️
|
|
335
|
+
// ⚠️ rawResult contient le résultat brut du tool (ToolContractOutput)
|
|
126
336
|
// Si content est undefined, on sérialise rawResult pour préserver la structure JSON complète
|
|
127
|
-
// Sinon, on utilise result complet comme fallback
|
|
128
337
|
output: result.content || JSON.stringify(result.rawResult || result)
|
|
129
338
|
});
|
|
130
339
|
}
|
|
131
|
-
//
|
|
132
|
-
// ✅ Les steps sont ajoutés APRÈS le follow-up dans readCompletionsStream
|
|
133
|
-
// pour éviter que le LLM pense que l'outil a déjà été exécuté
|
|
134
340
|
}
|
|
341
|
+
//
|
|
135
342
|
// ✅ NOTE: On ne gère PAS submitToolOutputs ici
|
|
136
343
|
// C'est readCompletionsStream qui décide selon hasTransfer
|
|
137
|
-
// On retourne juste les données nécessaires
|
|
138
344
|
return { results, needsFollowUp, parsedCalls, transferAgentName, hasTransfer, toolOutputs };
|
|
139
345
|
}
|
|
@@ -196,7 +196,7 @@ async function readCompletionsStream(params) {
|
|
|
196
196
|
const transferredAgent = agents.find(a => a.name === transferAgentName) || agentConfig;
|
|
197
197
|
const instructions = transferredAgent.instructions;
|
|
198
198
|
const enrichedInstructions = (await params.enrichWithMemory?.("system", transferredAgent, context)) || '';
|
|
199
|
-
// ✅ Set préserve le trail existant via
|
|
199
|
+
// ✅ Set préserve le trail existant via updateSystemContextTrail()
|
|
200
200
|
stateGraph.set(discussionRootAgent, instructions + '\n' + enrichedInstructions);
|
|
201
201
|
}
|
|
202
202
|
//
|
|
@@ -221,9 +221,26 @@ async function readCompletionsStream(params) {
|
|
|
221
221
|
const followUpAgent = agents.find(a => a.name === followUpAgentName) || currentAgent;
|
|
222
222
|
const tools = followUpAgent.tools || [];
|
|
223
223
|
//
|
|
224
|
-
// Responses API
|
|
224
|
+
// Responses API — previous_response_id (intra-turn, follow-up après tool calls)
|
|
225
|
+
//
|
|
226
|
+
// Si final.id disponible ET pas de transfer : previous_response_id + uniquement les function_call_output.
|
|
227
|
+
// L'historique complet (system, user, assistant+tools) est encodé dans final.id.
|
|
228
|
+
//
|
|
229
|
+
// ⚠️ Transfer case : le system prompt a changé (nouvelles instructions de l'agent destination).
|
|
230
|
+
// previous_response_id cacherait l'ANCIEN system prompt (orientation) → agent destination
|
|
231
|
+
// ne recevrait pas ses propres instructions. On envoie l'historique complet.
|
|
225
232
|
const followUpOptions = Object.assign({}, (0, modelconfig_1.modelConfig)(followUpAgent.model, {}, true)); // forResponses=true
|
|
226
|
-
|
|
233
|
+
if (final.id && !hasTransfer) {
|
|
234
|
+
followUpOptions.previous_response_id = final.id;
|
|
235
|
+
followUpOptions.input = toolOutputs.map(o => ({
|
|
236
|
+
type: 'function_call_output',
|
|
237
|
+
call_id: o.call_id,
|
|
238
|
+
output: o.output
|
|
239
|
+
}));
|
|
240
|
+
}
|
|
241
|
+
else {
|
|
242
|
+
followUpOptions.input = (0, shared_1.convertMessagesToResponsesInput)(discussion.messages);
|
|
243
|
+
}
|
|
227
244
|
if (tools.length > 0) {
|
|
228
245
|
followUpOptions.tools = tools;
|
|
229
246
|
followUpOptions.tool_choice = "auto";
|
|
@@ -236,12 +253,11 @@ async function readCompletionsStream(params) {
|
|
|
236
253
|
for (let i = 0; i < results.length; i++) {
|
|
237
254
|
const result = results[i];
|
|
238
255
|
const toolCall = parsedCalls[i];
|
|
256
|
+
const reason = result.context ? `${result.context} (${toolCall.args.justification})` : toolCall.args.justification;
|
|
239
257
|
if (result.name) {
|
|
240
258
|
stateGraph.addStep(discussionRootAgent, {
|
|
241
259
|
tool: result.name,
|
|
242
|
-
|
|
243
|
-
reason: toolCall.args.justification || '',
|
|
244
|
-
id: result.id
|
|
260
|
+
reason
|
|
245
261
|
});
|
|
246
262
|
}
|
|
247
263
|
}
|
|
@@ -294,6 +310,12 @@ async function readCompletionsStream(params) {
|
|
|
294
310
|
if (followUpContent) {
|
|
295
311
|
stateGraph.push(discussionRootAgent, { role: "assistant", content: followUpContent });
|
|
296
312
|
}
|
|
313
|
+
//
|
|
314
|
+
// ✅ Base case intra-turn : mettre à jour lastResponseId pour le prochain tour.
|
|
315
|
+
if (followUpFinal.id) {
|
|
316
|
+
discussion.lastResponseId = followUpFinal.id;
|
|
317
|
+
discussion.lastResponseMsgCount = discussion.messages.length;
|
|
318
|
+
}
|
|
297
319
|
}
|
|
298
320
|
}
|
|
299
321
|
else if (content) {
|
|
@@ -301,6 +323,12 @@ async function readCompletionsStream(params) {
|
|
|
301
323
|
if (verbose)
|
|
302
324
|
console.log("✅ Agent (Responses): save content without tool calls:", content?.length);
|
|
303
325
|
stateGraph.push(discussionRootAgent, { role: "assistant", content });
|
|
326
|
+
//
|
|
327
|
+
// ✅ Base case direct : mettre à jour lastResponseId pour le prochain tour.
|
|
328
|
+
if (final.id) {
|
|
329
|
+
discussion.lastResponseId = final.id;
|
|
330
|
+
discussion.lastResponseMsgCount = discussion.messages.length;
|
|
331
|
+
}
|
|
304
332
|
}
|
|
305
333
|
//
|
|
306
334
|
// ✅ OPTIM: Utiliser helper centralisé
|
|
@@ -315,7 +343,15 @@ async function readCompletionsStream(params) {
|
|
|
315
343
|
async function executeAgentSet(agentSet, context, params) {
|
|
316
344
|
const { query, verbose } = params;
|
|
317
345
|
const openai = (0, llm_1.llmInstance)();
|
|
318
|
-
|
|
346
|
+
//
|
|
347
|
+
// injectSubAgentTools retourne un tableau plat : copies des parents (tools injectés)
|
|
348
|
+
// + configs complètes des subAgents (instructions+tools+toolLogic pour handleSubAgentCall)
|
|
349
|
+
const agents = (0, utils_1.injectTransferTools)((0, utils_1.injectSubAgentTools)(agentSet));
|
|
350
|
+
//
|
|
351
|
+
// Propager stdout dans le contexte pour les tools (ex: Worker sendFeedback)
|
|
352
|
+
if (params.stdout) {
|
|
353
|
+
context.stdout = params.stdout;
|
|
354
|
+
}
|
|
319
355
|
const discussionRootAgent = params.home || agents[0].name;
|
|
320
356
|
const stateGraph = (0, stategraph_1.sessionStateGraphGet)(context);
|
|
321
357
|
const discussion = stateGraph.createOrRestore(discussionRootAgent);
|
|
@@ -345,25 +381,22 @@ async function executeAgentSet(agentSet, context, params) {
|
|
|
345
381
|
// - https://community.openai.com/t/appropriate-role-for-context-message-in-query-in-rag/867231
|
|
346
382
|
//
|
|
347
383
|
const enrichedInstructions = await params.enrichWithMemory?.("system", currentAgentConfig, context);
|
|
384
|
+
//
|
|
385
|
+
// ✅ Toujours rafraîchir le system prompt au début de chaque tour.
|
|
386
|
+
// - Nouvelle discussion : initialiser usage + injecter instructions
|
|
387
|
+
// - Discussion existante : réinitialiser les instructions de l'agent HOME
|
|
388
|
+
//
|
|
389
|
+
// ⚠️ Sans ce reset systématique, un transfer précédent peut avoir remplacé le system prompt
|
|
390
|
+
// de la discussion home avec les instructions de l'agent destination. Au tour suivant,
|
|
391
|
+
// l'agent home démarrerait avec le mauvais prompt (ex: "orientation" avec instructions "guess-word").
|
|
392
|
+
// stateGraph.set() préserve le context-trail existant (via updateSystemContextTrail).
|
|
393
|
+
const instructions = currentAgentConfig.instructions + '\n' + (enrichedInstructions || '');
|
|
348
394
|
if (!discussion.messages.length) {
|
|
349
|
-
//
|
|
350
|
-
// New discussion: initialize usage and set system message
|
|
351
395
|
discussion.usage = { prompt: 0, completion: 0, total: 0, cost: 0 };
|
|
352
|
-
const instructions = currentAgentConfig.instructions + '\n' + (enrichedInstructions || '');
|
|
353
|
-
stateGraph.set(discussionRootAgent, instructions);
|
|
354
|
-
}
|
|
355
|
-
else if (enrichedInstructions) {
|
|
356
|
-
//
|
|
357
|
-
// Existing discussion: only update system message if enrichedInstructions exists
|
|
358
|
-
// stateGraph.set() preserves context-trail via updateSystemMessage()
|
|
359
|
-
const instructions = currentAgentConfig.instructions + '\n' + enrichedInstructions;
|
|
360
|
-
stateGraph.set(discussionRootAgent, instructions);
|
|
361
396
|
}
|
|
397
|
+
stateGraph.set(discussionRootAgent, instructions);
|
|
362
398
|
stateGraph.push(discussionRootAgent, { role: "user", content: enrichedQuery });
|
|
363
399
|
const tools = currentAgentConfig.tools;
|
|
364
|
-
if (verbose) {
|
|
365
|
-
console.log('--- DBG current agent (Responses)', currentAgentConfig.name, `reasoning:${params.thinking}`, 'memory len:', discussion.messages.length);
|
|
366
|
-
}
|
|
367
400
|
let result = (0, types_1.enrichExecutionResult)({
|
|
368
401
|
runId: `${discussionRootAgent}-${Date.now()}`,
|
|
369
402
|
startQuery: query,
|
|
@@ -383,18 +416,29 @@ async function executeAgentSet(agentSet, context, params) {
|
|
|
383
416
|
//
|
|
384
417
|
// Responses API: utiliser modelConfig avec forResponses=true pour reasoning: { effort }
|
|
385
418
|
const model = (0, modelconfig_1.modelConfig)(currentAgentConfig.model, { thinking: params.thinking }, true);
|
|
386
|
-
const options = Object.assign({}, model);
|
|
419
|
+
const options = (0, shared_1.applyResponseTextFormat)(Object.assign({}, model), params);
|
|
387
420
|
//
|
|
388
|
-
//
|
|
389
|
-
// Actuellement uniquement implémenté dans executeAgent (ligne 456)
|
|
390
|
-
// Pour améliorer le contexte multi-tours, stocker response.id dans discussion/stateGraph
|
|
391
|
-
// et l'utiliser dans les appels suivants:
|
|
392
|
-
// if (discussion.lastResponseId) {
|
|
393
|
-
// options.previous_response_id = discussion.lastResponseId;
|
|
394
|
-
// }
|
|
421
|
+
// Responses API — previous_response_id (inter-turn)
|
|
395
422
|
//
|
|
396
|
-
//
|
|
397
|
-
|
|
423
|
+
// Si la discussion a un lastResponseId (fin d'un tour précédent), envoyer uniquement
|
|
424
|
+
// le delta de messages (system mis à jour + nouveau message user) plutôt que
|
|
425
|
+
// l'historique complet. Le contexte est récupéré côté OpenAI via previous_response_id.
|
|
426
|
+
//
|
|
427
|
+
// Messages[0] (system) est toujours inclus pour propager les instructions mises à jour
|
|
428
|
+
// (enrichedInstructions, context-trail). Les messages depuis lastResponseMsgCount sont
|
|
429
|
+
// les nouveaux messages du tour courant (typiquement : le message user).
|
|
430
|
+
if (discussion.lastResponseId && discussion.lastResponseMsgCount !== undefined) {
|
|
431
|
+
const deltaMessages = discussion.messages.slice(discussion.lastResponseMsgCount);
|
|
432
|
+
const systemMsg = discussion.messages[0]; // Toujours envoyer le system (instructions à jour)
|
|
433
|
+
const inputMessages = systemMsg?.role === 'system' ? [systemMsg, ...deltaMessages] : deltaMessages;
|
|
434
|
+
options.input = (0, shared_1.convertMessagesToResponsesInput)(inputMessages);
|
|
435
|
+
options.previous_response_id = discussion.lastResponseId;
|
|
436
|
+
if (verbose)
|
|
437
|
+
console.log(`🔁 previous_response_id (inter-turn): ${discussion.lastResponseId}, delta: ${deltaMessages.length} msgs`);
|
|
438
|
+
}
|
|
439
|
+
else {
|
|
440
|
+
options.input = (0, shared_1.convertMessagesToResponsesInput)(discussion.messages);
|
|
441
|
+
}
|
|
398
442
|
if (tools.length > 0) {
|
|
399
443
|
options.tools = tools;
|
|
400
444
|
options.tool_choice = "auto";
|
|
@@ -438,8 +482,11 @@ async function executeAgentSet(agentSet, context, params) {
|
|
|
438
482
|
result.actions = (0, helpers_1.stepsToActions)(stateGraph, discussionRootAgent);
|
|
439
483
|
// 💾 Auto-save du StateGraph à la fin
|
|
440
484
|
(0, stategraph_1.sessionStateGraphSet)(context, stateGraph);
|
|
441
|
-
// finalize result
|
|
442
|
-
|
|
485
|
+
// finalize result — ne pas écraser si une erreur a déjà été capturée (ex: quota, timeout)
|
|
486
|
+
const lastDiscussionMsg = discussion.messages?.[discussion.messages.length - 1]?.content || '';
|
|
487
|
+
if (!result.error || lastDiscussionMsg) {
|
|
488
|
+
result.lastMessage = lastDiscussionMsg || result.lastMessage;
|
|
489
|
+
}
|
|
443
490
|
if (discussion?.usage) {
|
|
444
491
|
result.usage = {
|
|
445
492
|
prompt: discussion.usage.prompt || 0,
|
|
@@ -472,9 +519,6 @@ async function executeAgent(agentSet, params) {
|
|
|
472
519
|
let state = '';
|
|
473
520
|
let maxIterations = 10;
|
|
474
521
|
let iterations = 0;
|
|
475
|
-
if (verbose) {
|
|
476
|
-
console.log('--- DBG executeAgent (Responses):', agent.name);
|
|
477
|
-
}
|
|
478
522
|
if (debug) {
|
|
479
523
|
console.log('--- DBG executeAgent-system (Responses):', agent.instructions);
|
|
480
524
|
console.log('--- DBG executeAgent-user:', query);
|
|
@@ -555,24 +599,6 @@ async function executeQuery(params) {
|
|
|
555
599
|
}
|
|
556
600
|
const openai = (0, llm_1.llmInstance)();
|
|
557
601
|
const model = (0, modelconfig_1.modelConfig)(modelName, {}, true); // forResponses=true
|
|
558
|
-
// Responses API: response_format → text.format
|
|
559
|
-
// Fusionner avec text.verbosity qui peut venir de modelConfig
|
|
560
|
-
if (params.json || params.schema) {
|
|
561
|
-
const format = {};
|
|
562
|
-
if (params.schema) {
|
|
563
|
-
// Structured Outputs: type "json_schema" avec schema et strict
|
|
564
|
-
format.type = "json_schema";
|
|
565
|
-
format.name = "response_schema";
|
|
566
|
-
format.schema = params.schema;
|
|
567
|
-
format.strict = true;
|
|
568
|
-
}
|
|
569
|
-
else if (params.json) {
|
|
570
|
-
// JSON mode simple
|
|
571
|
-
format.type = "json_object";
|
|
572
|
-
}
|
|
573
|
-
// Fusionner avec text existant (verbosity)
|
|
574
|
-
model.text = Object.assign({}, model.text || {}, { format });
|
|
575
|
-
}
|
|
576
602
|
if (verbose) {
|
|
577
603
|
console.log('--- DBG query (Responses):', modelName, `${query?.substring(0, 100)}...`);
|
|
578
604
|
}
|
|
@@ -581,7 +607,7 @@ async function executeQuery(params) {
|
|
|
581
607
|
let usage = { prompt: 0, completion: 0, total: 0, cost: 0 };
|
|
582
608
|
let state = '';
|
|
583
609
|
try {
|
|
584
|
-
const options = Object.assign({}, model);
|
|
610
|
+
const options = (0, shared_1.applyResponseTextFormat)(Object.assign({}, model), params);
|
|
585
611
|
options.input = messages;
|
|
586
612
|
// Responses API: utiliser instructions au lieu de role: "system" si fourni
|
|
587
613
|
if (instructions) {
|
|
@@ -29,6 +29,11 @@ export interface ExecuteAgentSetParams {
|
|
|
29
29
|
schema?: any;
|
|
30
30
|
debug?: boolean;
|
|
31
31
|
}
|
|
32
|
+
/**
|
|
33
|
+
* Applique le format de sortie Responses API (JSON mode ou JSON Schema strict)
|
|
34
|
+
* sans écraser d'autres options `text` déjà présentes (ex: verbosity).
|
|
35
|
+
*/
|
|
36
|
+
export declare function applyResponseTextFormat(options: Record<string, any>, params: Pick<ExecuteAgentSetParams, 'json' | 'schema'>): Record<string, any>;
|
|
32
37
|
/**
|
|
33
38
|
* Normalise les options pour l'API Responses
|
|
34
39
|
*
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.DummyWritable = void 0;
|
|
4
4
|
exports.sendFeedback = sendFeedback;
|
|
5
|
+
exports.applyResponseTextFormat = applyResponseTextFormat;
|
|
5
6
|
exports.normalizeOptionsForResponses = normalizeOptionsForResponses;
|
|
6
7
|
exports.normalizedFunctionCallFromResponse = normalizedFunctionCallFromResponse;
|
|
7
8
|
exports.normalizeOutputFromResponses = normalizeOutputFromResponses;
|
|
@@ -35,6 +36,32 @@ function sendFeedback(params) {
|
|
|
35
36
|
// send agent state and description
|
|
36
37
|
stdout.write(`\n<step>${JSON.stringify(feedback)}</step>\n`);
|
|
37
38
|
}
|
|
39
|
+
/**
|
|
40
|
+
* Applique le format de sortie Responses API (JSON mode ou JSON Schema strict)
|
|
41
|
+
* sans écraser d'autres options `text` déjà présentes (ex: verbosity).
|
|
42
|
+
*/
|
|
43
|
+
function applyResponseTextFormat(options, params) {
|
|
44
|
+
if (!params.json && !params.schema) {
|
|
45
|
+
return options;
|
|
46
|
+
}
|
|
47
|
+
const format = params.schema
|
|
48
|
+
? {
|
|
49
|
+
type: 'json_schema',
|
|
50
|
+
name: 'response_schema',
|
|
51
|
+
schema: params.schema,
|
|
52
|
+
strict: true
|
|
53
|
+
}
|
|
54
|
+
: {
|
|
55
|
+
type: 'json_object'
|
|
56
|
+
};
|
|
57
|
+
return {
|
|
58
|
+
...options,
|
|
59
|
+
text: {
|
|
60
|
+
...(options.text || {}),
|
|
61
|
+
format
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
}
|
|
38
65
|
/**
|
|
39
66
|
* Normalise les options pour l'API Responses
|
|
40
67
|
*
|
package/dist/src/index.d.ts
CHANGED
|
@@ -14,9 +14,9 @@ export * from './scrapper';
|
|
|
14
14
|
export * from './prompts';
|
|
15
15
|
export * from './agents/reducer';
|
|
16
16
|
export * from './agents/prompts';
|
|
17
|
-
export * from './agents/semantic';
|
|
18
17
|
export * from './agents/system';
|
|
19
18
|
export * from './agents/job.runner';
|
|
19
|
+
export * from './agents/subagent';
|
|
20
20
|
export * from './rag';
|
|
21
21
|
export * from './usecase';
|
|
22
22
|
export * from './rules';
|
|
@@ -25,3 +25,4 @@ export * from './agents/simulator.types';
|
|
|
25
25
|
export * from './agents/simulator.prompts';
|
|
26
26
|
export * from './agents/simulator.utils';
|
|
27
27
|
export * from './agents/simulator.dashboard';
|
|
28
|
+
export * from './agents/worker.executor';
|
package/dist/src/index.js
CHANGED
|
@@ -52,9 +52,9 @@ __exportStar(require("./prompts"), exports);
|
|
|
52
52
|
// Agents
|
|
53
53
|
__exportStar(require("./agents/reducer"), exports);
|
|
54
54
|
__exportStar(require("./agents/prompts"), exports);
|
|
55
|
-
__exportStar(require("./agents/semantic"), exports);
|
|
56
55
|
__exportStar(require("./agents/system"), exports);
|
|
57
56
|
__exportStar(require("./agents/job.runner"), exports);
|
|
57
|
+
__exportStar(require("./agents/subagent"), exports);
|
|
58
58
|
// RAG Library
|
|
59
59
|
__exportStar(require("./rag"), exports);
|
|
60
60
|
// Usecase
|
|
@@ -67,3 +67,5 @@ __exportStar(require("./agents/simulator.types"), exports);
|
|
|
67
67
|
__exportStar(require("./agents/simulator.prompts"), exports);
|
|
68
68
|
__exportStar(require("./agents/simulator.utils"), exports);
|
|
69
69
|
__exportStar(require("./agents/simulator.dashboard"), exports);
|
|
70
|
+
// Worker executor
|
|
71
|
+
__exportStar(require("./agents/worker.executor"), exports);
|
package/dist/src/llm/openai.js
CHANGED
|
@@ -103,8 +103,15 @@ exports.LLMopenai = {
|
|
|
103
103
|
verbosity: "low",
|
|
104
104
|
stream: true
|
|
105
105
|
},
|
|
106
|
+
"HIGH-codex": {
|
|
107
|
+
model: "gpt-5.3-codex",
|
|
108
|
+
reasoning_effort: "low",
|
|
109
|
+
verbosity: "low",
|
|
110
|
+
temperature: 1,
|
|
111
|
+
stream: true
|
|
112
|
+
},
|
|
106
113
|
"HIGH-fast": {
|
|
107
|
-
model: "gpt-5.
|
|
114
|
+
model: "gpt-5.4",
|
|
108
115
|
reasoning_effort: "none",
|
|
109
116
|
verbosity: "low",
|
|
110
117
|
temperature: 1,
|
package/dist/src/llm/pricing.js
CHANGED
|
@@ -36,6 +36,8 @@ exports.modelPricing = {
|
|
|
36
36
|
"gpt-5": { input: 0.00000125, output: 0.00001 },
|
|
37
37
|
"gpt-5.1": { input: 0.00000125, output: 0.00001 },
|
|
38
38
|
"gpt-5.2": { input: 0.00000175, cachedInput: 0.000000175, output: 0.000014 },
|
|
39
|
+
"gpt-5.3-codex": { input: 0.00000175, cachedInput: 0.000000175, output: 0.000014 },
|
|
40
|
+
"gpt-5.4": { input: 0.0000025, cachedInput: 0.00000025, output: 0.000015 },
|
|
39
41
|
"gpt-5-mini": { input: 0.00000025, output: 0.000002 },
|
|
40
42
|
"gpt-5-nano": { input: 0.00000005, output: 0.0000004 },
|
|
41
43
|
// OpenAI o-series
|