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.
Files changed (59) hide show
  1. package/dist/src/agents/prompts.d.ts +2 -3
  2. package/dist/src/agents/prompts.js +21 -118
  3. package/dist/src/agents/reducer.loaders.d.ts +103 -1
  4. package/dist/src/agents/reducer.loaders.js +164 -2
  5. package/dist/src/agents/reducer.types.d.ts +34 -3
  6. package/dist/src/agents/simulator.d.ts +32 -2
  7. package/dist/src/agents/simulator.executor.d.ts +15 -5
  8. package/dist/src/agents/simulator.executor.js +134 -67
  9. package/dist/src/agents/simulator.js +251 -8
  10. package/dist/src/agents/simulator.prompts.d.ts +55 -10
  11. package/dist/src/agents/simulator.prompts.js +305 -61
  12. package/dist/src/agents/simulator.types.d.ts +62 -1
  13. package/dist/src/agents/simulator.types.js +5 -0
  14. package/dist/src/agents/subagent.d.ts +128 -0
  15. package/dist/src/agents/subagent.js +231 -0
  16. package/dist/src/agents/worker.executor.d.ts +48 -0
  17. package/dist/src/agents/worker.executor.js +152 -0
  18. package/dist/src/execute/helpers.d.ts +3 -0
  19. package/dist/src/execute/helpers.js +222 -16
  20. package/dist/src/execute/responses.js +81 -55
  21. package/dist/src/execute/shared.d.ts +5 -0
  22. package/dist/src/execute/shared.js +27 -0
  23. package/dist/src/index.d.ts +2 -1
  24. package/dist/src/index.js +3 -1
  25. package/dist/src/llm/openai.js +8 -1
  26. package/dist/src/llm/pricing.js +2 -0
  27. package/dist/src/llm/xai.js +11 -6
  28. package/dist/src/prompts.d.ts +14 -0
  29. package/dist/src/prompts.js +41 -1
  30. package/dist/src/rag/rag.manager.d.ts +18 -3
  31. package/dist/src/rag/rag.manager.js +114 -12
  32. package/dist/src/rag/types.d.ts +3 -1
  33. package/dist/src/rules/git/git.e2e.helper.js +51 -4
  34. package/dist/src/rules/git/git.health.js +89 -56
  35. package/dist/src/rules/git/index.d.ts +2 -2
  36. package/dist/src/rules/git/index.js +22 -5
  37. package/dist/src/rules/git/repo.d.ts +64 -6
  38. package/dist/src/rules/git/repo.js +572 -141
  39. package/dist/src/rules/git/repo.pr.d.ts +11 -18
  40. package/dist/src/rules/git/repo.pr.js +82 -94
  41. package/dist/src/rules/git/repo.tools.d.ts +5 -0
  42. package/dist/src/rules/git/repo.tools.js +6 -1
  43. package/dist/src/rules/types.d.ts +0 -2
  44. package/dist/src/rules/utils.matter.js +1 -5
  45. package/dist/src/scrapper.d.ts +138 -25
  46. package/dist/src/scrapper.js +538 -160
  47. package/dist/src/stategraph/stategraph.d.ts +6 -2
  48. package/dist/src/stategraph/stategraph.js +21 -6
  49. package/dist/src/stategraph/types.d.ts +14 -6
  50. package/dist/src/types.d.ts +22 -0
  51. package/dist/src/utils.d.ts +24 -0
  52. package/dist/src/utils.js +84 -86
  53. package/package.json +3 -2
  54. package/dist/src/agents/semantic.d.ts +0 -4
  55. package/dist/src/agents/semantic.js +0 -19
  56. package/dist/src/execute/legacy.d.ts +0 -46
  57. package/dist/src/execute/legacy.js +0 -460
  58. package/dist/src/pricing.llm.d.ts +0 -5
  59. 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.context,
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
- // Traiter tous les tool calls
106
- for (const toolCall of parsedCalls) {
107
- const result = await (0, utils_1.handleTransferCall)(discussion, currentAgentRef, agents, toolCall, context);
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.did_transfer || result.rawResult) {
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
- // ⚠️ ATTENTION: rawResult contient le résultat brut du tool (ToolContractOutput)
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 updateSystemMessage()
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: utiliser input au lieu de messages
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
- followUpOptions.input = (0, shared_1.convertMessagesToResponsesInput)(discussion.messages);
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
- context: result.context || '',
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
- const agents = (0, utils_1.injectTransferTools)(agentSet);
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
- // TODO [Phase 3]: Ajouter support de previous_response_id dans executeAgentSet
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
- // Responses API: utiliser input au lieu de messages
397
- options.input = (0, shared_1.convertMessagesToResponsesInput)(discussion.messages);
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
- result.lastMessage = discussion.messages?.[discussion.messages.length - 1]?.content || '';
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
  *
@@ -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);
@@ -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.2",
114
+ model: "gpt-5.4",
108
115
  reasoning_effort: "none",
109
116
  verbosity: "low",
110
117
  temperature: 1,
@@ -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