agentic-api 2.0.684 → 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 (56) hide show
  1. package/dist/src/agents/prompts.d.ts +2 -3
  2. package/dist/src/agents/prompts.js +13 -109
  3. package/dist/src/agents/reducer.loaders.d.ts +46 -15
  4. package/dist/src/agents/reducer.loaders.js +76 -21
  5. package/dist/src/agents/reducer.types.d.ts +30 -3
  6. package/dist/src/agents/simulator.d.ts +3 -2
  7. package/dist/src/agents/simulator.executor.d.ts +8 -2
  8. package/dist/src/agents/simulator.executor.js +62 -26
  9. package/dist/src/agents/simulator.js +100 -11
  10. package/dist/src/agents/simulator.prompts.d.ts +48 -21
  11. package/dist/src/agents/simulator.prompts.js +289 -122
  12. package/dist/src/agents/simulator.types.d.ts +33 -1
  13. package/dist/src/agents/subagent.d.ts +128 -0
  14. package/dist/src/agents/subagent.js +231 -0
  15. package/dist/src/agents/worker.executor.d.ts +48 -0
  16. package/dist/src/agents/worker.executor.js +152 -0
  17. package/dist/src/execute/helpers.d.ts +3 -0
  18. package/dist/src/execute/helpers.js +221 -15
  19. package/dist/src/execute/responses.js +78 -51
  20. package/dist/src/execute/shared.d.ts +5 -0
  21. package/dist/src/execute/shared.js +27 -0
  22. package/dist/src/index.d.ts +2 -1
  23. package/dist/src/index.js +3 -1
  24. package/dist/src/llm/openai.js +8 -1
  25. package/dist/src/llm/pricing.js +2 -0
  26. package/dist/src/llm/xai.js +11 -6
  27. package/dist/src/prompts.d.ts +14 -0
  28. package/dist/src/prompts.js +41 -1
  29. package/dist/src/rag/rag.manager.d.ts +18 -3
  30. package/dist/src/rag/rag.manager.js +91 -5
  31. package/dist/src/rules/git/git.e2e.helper.js +3 -0
  32. package/dist/src/rules/git/git.health.js +88 -57
  33. package/dist/src/rules/git/index.d.ts +1 -1
  34. package/dist/src/rules/git/index.js +13 -5
  35. package/dist/src/rules/git/repo.d.ts +25 -6
  36. package/dist/src/rules/git/repo.js +430 -146
  37. package/dist/src/rules/git/repo.pr.js +45 -13
  38. package/dist/src/rules/git/repo.tools.d.ts +5 -0
  39. package/dist/src/rules/git/repo.tools.js +6 -1
  40. package/dist/src/rules/types.d.ts +0 -2
  41. package/dist/src/rules/utils.matter.js +1 -5
  42. package/dist/src/scrapper.d.ts +138 -25
  43. package/dist/src/scrapper.js +538 -160
  44. package/dist/src/stategraph/stategraph.d.ts +4 -0
  45. package/dist/src/stategraph/stategraph.js +16 -0
  46. package/dist/src/stategraph/types.d.ts +13 -1
  47. package/dist/src/types.d.ts +21 -0
  48. package/dist/src/utils.d.ts +24 -0
  49. package/dist/src/utils.js +84 -86
  50. package/package.json +3 -2
  51. package/dist/src/agents/semantic.d.ts +0 -4
  52. package/dist/src/agents/semantic.js +0 -19
  53. package/dist/src/execute/legacy.d.ts +0 -46
  54. package/dist/src/execute/legacy.js +0 -460
  55. package/dist/src/pricing.llm.d.ts +0 -5
  56. 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
  *
@@ -49,6 +101,150 @@ function stepsToActions(stateGraph, agentName) {
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
  }
@@ -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";
@@ -293,6 +310,12 @@ async function readCompletionsStream(params) {
293
310
  if (followUpContent) {
294
311
  stateGraph.push(discussionRootAgent, { role: "assistant", content: followUpContent });
295
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
+ }
296
319
  }
297
320
  }
298
321
  else if (content) {
@@ -300,6 +323,12 @@ async function readCompletionsStream(params) {
300
323
  if (verbose)
301
324
  console.log("✅ Agent (Responses): save content without tool calls:", content?.length);
302
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
+ }
303
332
  }
304
333
  //
305
334
  // ✅ OPTIM: Utiliser helper centralisé
@@ -314,7 +343,15 @@ async function readCompletionsStream(params) {
314
343
  async function executeAgentSet(agentSet, context, params) {
315
344
  const { query, verbose } = params;
316
345
  const openai = (0, llm_1.llmInstance)();
317
- 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
+ }
318
355
  const discussionRootAgent = params.home || agents[0].name;
319
356
  const stateGraph = (0, stategraph_1.sessionStateGraphGet)(context);
320
357
  const discussion = stateGraph.createOrRestore(discussionRootAgent);
@@ -344,25 +381,22 @@ async function executeAgentSet(agentSet, context, params) {
344
381
  // - https://community.openai.com/t/appropriate-role-for-context-message-in-query-in-rag/867231
345
382
  //
346
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 || '');
347
394
  if (!discussion.messages.length) {
348
- //
349
- // New discussion: initialize usage and set system message
350
395
  discussion.usage = { prompt: 0, completion: 0, total: 0, cost: 0 };
351
- const instructions = currentAgentConfig.instructions + '\n' + (enrichedInstructions || '');
352
- stateGraph.set(discussionRootAgent, instructions);
353
- }
354
- else if (enrichedInstructions) {
355
- //
356
- // Existing discussion: only update system message if enrichedInstructions exists
357
- // stateGraph.set() preserves context-trail via updateSystemContextTrail()
358
- const instructions = currentAgentConfig.instructions + '\n' + enrichedInstructions;
359
- stateGraph.set(discussionRootAgent, instructions);
360
396
  }
397
+ stateGraph.set(discussionRootAgent, instructions);
361
398
  stateGraph.push(discussionRootAgent, { role: "user", content: enrichedQuery });
362
399
  const tools = currentAgentConfig.tools;
363
- if (verbose) {
364
- console.log('--- DBG current agent (Responses)', currentAgentConfig.name, `reasoning:${params.thinking}`, 'memory len:', discussion.messages.length);
365
- }
366
400
  let result = (0, types_1.enrichExecutionResult)({
367
401
  runId: `${discussionRootAgent}-${Date.now()}`,
368
402
  startQuery: query,
@@ -382,18 +416,29 @@ async function executeAgentSet(agentSet, context, params) {
382
416
  //
383
417
  // Responses API: utiliser modelConfig avec forResponses=true pour reasoning: { effort }
384
418
  const model = (0, modelconfig_1.modelConfig)(currentAgentConfig.model, { thinking: params.thinking }, true);
385
- const options = Object.assign({}, model);
419
+ const options = (0, shared_1.applyResponseTextFormat)(Object.assign({}, model), params);
386
420
  //
387
- // TODO [Phase 3]: Ajouter support de previous_response_id dans executeAgentSet
388
- // Actuellement uniquement implémenté dans executeAgent (ligne 456)
389
- // Pour améliorer le contexte multi-tours, stocker response.id dans discussion/stateGraph
390
- // et l'utiliser dans les appels suivants:
391
- // if (discussion.lastResponseId) {
392
- // options.previous_response_id = discussion.lastResponseId;
393
- // }
421
+ // Responses API previous_response_id (inter-turn)
394
422
  //
395
- // Responses API: utiliser input au lieu de messages
396
- 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
+ }
397
442
  if (tools.length > 0) {
398
443
  options.tools = tools;
399
444
  options.tool_choice = "auto";
@@ -437,8 +482,11 @@ async function executeAgentSet(agentSet, context, params) {
437
482
  result.actions = (0, helpers_1.stepsToActions)(stateGraph, discussionRootAgent);
438
483
  // 💾 Auto-save du StateGraph à la fin
439
484
  (0, stategraph_1.sessionStateGraphSet)(context, stateGraph);
440
- // finalize result
441
- 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
+ }
442
490
  if (discussion?.usage) {
443
491
  result.usage = {
444
492
  prompt: discussion.usage.prompt || 0,
@@ -471,9 +519,6 @@ async function executeAgent(agentSet, params) {
471
519
  let state = '';
472
520
  let maxIterations = 10;
473
521
  let iterations = 0;
474
- if (verbose) {
475
- console.log('--- DBG executeAgent (Responses):', agent.name);
476
- }
477
522
  if (debug) {
478
523
  console.log('--- DBG executeAgent-system (Responses):', agent.instructions);
479
524
  console.log('--- DBG executeAgent-user:', query);
@@ -554,24 +599,6 @@ async function executeQuery(params) {
554
599
  }
555
600
  const openai = (0, llm_1.llmInstance)();
556
601
  const model = (0, modelconfig_1.modelConfig)(modelName, {}, true); // forResponses=true
557
- // Responses API: response_format → text.format
558
- // Fusionner avec text.verbosity qui peut venir de modelConfig
559
- if (params.json || params.schema) {
560
- const format = {};
561
- if (params.schema) {
562
- // Structured Outputs: type "json_schema" avec schema et strict
563
- format.type = "json_schema";
564
- format.name = "response_schema";
565
- format.schema = params.schema;
566
- format.strict = true;
567
- }
568
- else if (params.json) {
569
- // JSON mode simple
570
- format.type = "json_object";
571
- }
572
- // Fusionner avec text existant (verbosity)
573
- model.text = Object.assign({}, model.text || {}, { format });
574
- }
575
602
  if (verbose) {
576
603
  console.log('--- DBG query (Responses):', modelName, `${query?.substring(0, 100)}...`);
577
604
  }
@@ -580,7 +607,7 @@ async function executeQuery(params) {
580
607
  let usage = { prompt: 0, completion: 0, total: 0, cost: 0 };
581
608
  let state = '';
582
609
  try {
583
- const options = Object.assign({}, model);
610
+ const options = (0, shared_1.applyResponseTextFormat)(Object.assign({}, model), params);
584
611
  options.input = messages;
585
612
  // Responses API: utiliser instructions au lieu de role: "system" si fourni
586
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
@@ -54,26 +54,31 @@ exports.LLMxai = {
54
54
  },
55
55
  "MEDIUM-fast": {
56
56
  temperature: 0.2,
57
- model: "grok-4-1-fast-reasoning",
57
+ model: "grok-4-1-fast-non-reasoning",
58
58
  stream: true
59
59
  },
60
60
  "MEDIUM": {
61
61
  temperature: 0.2,
62
- model: "grok-4-fast-reasoning",
62
+ model: "grok-4-1-fast-reasoning",
63
63
  stream: true
64
64
  },
65
65
  "HIGH-fast": {
66
- model: "grok-4-1-fast-reasoning",
66
+ model: "grok-4-1-fast-non-reasoning",
67
+ temperature: 0.2,
68
+ stream: true
69
+ },
70
+ "HIGH-codex": {
71
+ model: "grok-code-fast-1",
67
72
  temperature: 0.2,
68
73
  stream: true
69
74
  },
70
75
  "HIGH": {
71
- model: "grok-4",
76
+ model: "grok-4-1-fast-reasoning",
72
77
  temperature: 0.2,
73
78
  stream: true
74
79
  },
75
80
  "HIGH-medium": {
76
- model: "grok-4",
81
+ model: "grok-4-1-fast-non-reasoning",
77
82
  temperature: 0.2,
78
83
  stream: true
79
84
  },
@@ -84,7 +89,7 @@ exports.LLMxai = {
84
89
  },
85
90
  "SEARCH": {
86
91
  temperature: 0.2,
87
- model: "grok-4-fast-reasoning",
92
+ model: "grok-4-1-fast-non-reasoning",
88
93
  tools: [{ type: "web_search" }],
89
94
  },
90
95
  };