agentic-api 2.0.585 → 2.0.636

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.
@@ -0,0 +1,154 @@
1
+ "use strict";
2
+ /**
3
+ * Factory to create a ReducerFn compatible with JobRunner using MapLLM
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.createMapLLMReducer = createMapLLMReducer;
7
+ const reducer_core_1 = require("./reducer.core");
8
+ const reducer_loaders_1 = require("./reducer.loaders");
9
+ /**
10
+ * Default JSON schema for ReducedJobMemory
11
+ * Note: For strict mode, all properties must be in required array and
12
+ * all nested objects need additionalProperties: false
13
+ */
14
+ const DEFAULT_MEMORY_SCHEMA = {
15
+ name: 'ReducedJobMemory',
16
+ schema: {
17
+ type: 'object',
18
+ properties: {
19
+ memory: {
20
+ type: 'string',
21
+ description: 'Short canonical memory summarizing progress and key facts'
22
+ },
23
+ index: {
24
+ type: 'object',
25
+ description: 'Stable references: artifact IDs, data tables, error traces',
26
+ properties: {
27
+ artifacts: {
28
+ type: 'array',
29
+ items: { type: 'string' },
30
+ description: 'List of artifact references'
31
+ },
32
+ taskIds: {
33
+ type: 'array',
34
+ items: { type: 'string' },
35
+ description: 'List of completed task IDs'
36
+ },
37
+ errors: {
38
+ type: 'array',
39
+ items: { type: 'string' },
40
+ description: 'List of error messages'
41
+ }
42
+ },
43
+ required: ['artifacts', 'taskIds', 'errors'],
44
+ additionalProperties: false
45
+ },
46
+ statusLine: {
47
+ type: 'string',
48
+ description: 'UI progress line'
49
+ }
50
+ },
51
+ required: ['memory', 'index', 'statusLine'],
52
+ additionalProperties: false
53
+ },
54
+ strict: true
55
+ };
56
+ /**
57
+ * Creates a ReducerFn compatible with JobRunner that uses MapLLM internally.
58
+ *
59
+ * This factory bridges JobRunner and MapLLM, allowing LLM-powered reduction
60
+ * with structured outputs while keeping both modules independent.
61
+ *
62
+ * @example
63
+ * ```typescript
64
+ * const reducer = createMapLLMReducer({
65
+ * digestPrompt: "Analyze this task result and extract key facts...",
66
+ * reducePrompt: "Merge with previous memory to produce updated canonical memory...",
67
+ * model: 'LOW'
68
+ * });
69
+ *
70
+ * const runner = new JobRunner({
71
+ * planner: myPlanner,
72
+ * executor: myExecutor,
73
+ * reducer: reducer // ← ReducerFn compatible
74
+ * });
75
+ * ```
76
+ */
77
+ function createMapLLMReducer(options) {
78
+ const { digestPrompt, reducePrompt, format = DEFAULT_MEMORY_SCHEMA, model = 'LOW', finalReduce = true, reduceThresholdBytes, verbose = false } = options;
79
+ return async (previous, task, result) => {
80
+ // Serialize context for reduction
81
+ const context = JSON.stringify({
82
+ previousMemory: previous,
83
+ task: {
84
+ id: task.id,
85
+ title: task.title,
86
+ type: task.type
87
+ },
88
+ result: {
89
+ taskId: result.taskId,
90
+ ok: result.ok,
91
+ summary: result.summary,
92
+ error: result.error,
93
+ artifacts: result.artifacts,
94
+ // Include data if small enough, otherwise just note its presence
95
+ data: result.data && JSON.stringify(result.data).length < 2000
96
+ ? result.data
97
+ : (result.data ? '[data truncated]' : undefined)
98
+ }
99
+ }, null, 2);
100
+ // Create loader with single-chunk strategy (the context is already compact)
101
+ const loader = new reducer_loaders_1.StringNativeLoader(context, { type: 'paragraphs', size: 10 });
102
+ // Create MapLLM with options
103
+ const mapllmOptions = {
104
+ finalReduce,
105
+ reduceThresholdBytes
106
+ };
107
+ const mapper = new reducer_core_1.MapLLM(loader, mapllmOptions);
108
+ // Config for MapLLM
109
+ const config = {
110
+ digestPrompt,
111
+ reducePrompt
112
+ };
113
+ // Callback: accumulate structured output
114
+ const callback = (res, current) => {
115
+ // If current is already an object (structured output), use it directly
116
+ if (typeof current === 'object' && current !== null) {
117
+ res.acc = current;
118
+ }
119
+ else if (typeof current === 'string') {
120
+ // Try to parse as JSON
121
+ try {
122
+ res.acc = JSON.parse(current);
123
+ }
124
+ catch {
125
+ // Fallback: wrap in memory field
126
+ res.acc = {
127
+ memory: current,
128
+ index: res.acc?.index || {}
129
+ };
130
+ }
131
+ }
132
+ return res;
133
+ };
134
+ // Init with previous memory or empty
135
+ const init = {
136
+ acc: previous || { memory: '', index: {} },
137
+ config,
138
+ format,
139
+ model,
140
+ verbose
141
+ };
142
+ // Execute MapLLM reduce
143
+ const out = await mapper.reduce(callback, init);
144
+ // Validate and return
145
+ const result_acc = out.acc;
146
+ // Ensure required fields exist
147
+ const reducedMemory = {
148
+ memory: typeof result_acc.memory === 'string' ? result_acc.memory : JSON.stringify(result_acc.memory || ''),
149
+ index: typeof result_acc.index === 'object' ? result_acc.index : {},
150
+ statusLine: result_acc.statusLine
151
+ };
152
+ return reducedMemory;
153
+ };
154
+ }
@@ -17,3 +17,4 @@ Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./reducer.core"), exports);
18
18
  __exportStar(require("./reducer.loaders"), exports);
19
19
  __exportStar(require("./reducer.types"), exports);
20
+ __exportStar(require("./reducer.factory"), exports);
@@ -329,14 +329,35 @@ async function executeAgentSet(agentSet, context, params) {
329
329
  throw new Error(`Agent ${currentAgent} has no instructions`);
330
330
  }
331
331
  let enrichedQuery = query;
332
+ //
333
+ // ✅ FIX: Always refresh system prompt with latest memories (MEM_ALWAYS, rules, etc.)
334
+ // Before: enrichWithMemory("system") was only called for NEW discussions
335
+ // After: enrichWithMemory("system") is called on EVERY request to keep memories up-to-date
336
+ //
337
+ // TODO [Best Practice]: OpenAI recommande d'injecter le contexte dynamique (mémoires, RAG)
338
+ // dans un message "user" avec tag <context> plutôt que dans le system message.
339
+ // Raisons:
340
+ // - Hiérarchie des rôles: system > developer > user (sécurité contre prompt injection)
341
+ // - Séparation instructions stables (developer) vs contexte dynamique (user)
342
+ // Refs:
343
+ // - https://cookbook.openai.com/examples/agents_sdk/context_personalization
344
+ // - https://cookbook.openai.com/articles/openai-harmony
345
+ // - https://community.openai.com/t/appropriate-role-for-context-message-in-query-in-rag/867231
346
+ //
347
+ const enrichedInstructions = await params.enrichWithMemory?.("system", currentAgentConfig, context);
332
348
  if (!discussion.messages.length) {
349
+ //
350
+ // New discussion: initialize usage and set system message
333
351
  discussion.usage = { prompt: 0, completion: 0, total: 0, cost: 0 };
334
- const enrichedInstructions = await params.enrichWithMemory?.("system", currentAgentConfig, context);
335
- const instructions = currentAgentConfig.instructions + '\n' + enrichedInstructions;
352
+ const instructions = currentAgentConfig.instructions + '\n' + (enrichedInstructions || '');
336
353
  stateGraph.set(discussionRootAgent, instructions);
337
354
  }
338
- else {
339
- enrichedQuery = (await params.enrichWithMemory?.("user", currentAgentConfig, context)) || query;
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);
340
361
  }
341
362
  stateGraph.push(discussionRootAgent, { role: "user", content: enrichedQuery });
342
363
  const tools = currentAgentConfig.tools;
@@ -11,9 +11,12 @@ export type { LLMProvider, LLMConfig, ProviderConfig } from './llm';
11
11
  export { modelPricing, calculateCost, accumulateCost, LLM, LLMxai, LLMopenai } from './llm/pricing';
12
12
  export { modelConfig } from './execute/modelconfig';
13
13
  export * from './scrapper';
14
+ export * from './prompts';
14
15
  export * from './agents/reducer';
16
+ export * from './agents/prompts';
15
17
  export * from './agents/semantic';
16
18
  export * from './agents/system';
19
+ export * from './agents/job.runner';
17
20
  export * from './rag';
18
21
  export * from './usecase';
19
22
  export * from './rules';
package/dist/src/index.js CHANGED
@@ -47,10 +47,14 @@ var modelconfig_1 = require("./execute/modelconfig");
47
47
  Object.defineProperty(exports, "modelConfig", { enumerable: true, get: function () { return modelconfig_1.modelConfig; } });
48
48
  // Scrapper
49
49
  __exportStar(require("./scrapper"), exports);
50
+ // Prompts
51
+ __exportStar(require("./prompts"), exports);
50
52
  // Agents
51
53
  __exportStar(require("./agents/reducer"), exports);
54
+ __exportStar(require("./agents/prompts"), exports);
52
55
  __exportStar(require("./agents/semantic"), exports);
53
56
  __exportStar(require("./agents/system"), exports);
57
+ __exportStar(require("./agents/job.runner"), exports);
54
58
  // RAG Library
55
59
  __exportStar(require("./rag"), exports);
56
60
  // Usecase
@@ -47,6 +47,9 @@ export declare class RAGManager {
47
47
  /**
48
48
  * Notifie les embeddings chargés de se mettre à jour
49
49
  *
50
+ * Cette méthode est publique pour permettre aux applications de notifier
51
+ * les utilisateurs actifs du RAG (tools, search) qu'il a été mis à jour.
52
+ *
50
53
  * @param name Nom du RAG à mettre à jour
51
54
  * @param opts Options de mise à jour (action: 'rename' pour renommer un document)
52
55
  *
@@ -59,18 +62,22 @@ export declare class RAGManager {
59
62
  *
60
63
  * @example
61
64
  * ```typescript
62
- * // Après un build
63
- * this.notifyUpdate('procedures-stable');
65
+ * // Après un build externe
66
+ * ragManager.notifyUpdate('procedures-stable');
64
67
  *
65
68
  * // Après un rename de document
66
- * this.notifyUpdate('procedures-stable', {
69
+ * ragManager.notifyUpdate('procedures-stable', {
67
70
  * action: 'rename',
68
71
  * oldFile: 'old.md',
69
72
  * newFile: 'new.md'
70
73
  * });
71
74
  * ```
72
75
  */
73
- private notifyUpdate;
76
+ notifyUpdate(name: string, opts?: {
77
+ action?: 'rename';
78
+ oldFile?: string;
79
+ newFile?: string;
80
+ }): void;
74
81
  /**
75
82
  * Génère un nom d'archive avec timestamp YYYMMDD
76
83
  */
@@ -213,6 +213,9 @@ class RAGManager {
213
213
  /**
214
214
  * Notifie les embeddings chargés de se mettre à jour
215
215
  *
216
+ * Cette méthode est publique pour permettre aux applications de notifier
217
+ * les utilisateurs actifs du RAG (tools, search) qu'il a été mis à jour.
218
+ *
216
219
  * @param name Nom du RAG à mettre à jour
217
220
  * @param opts Options de mise à jour (action: 'rename' pour renommer un document)
218
221
  *
@@ -225,11 +228,11 @@ class RAGManager {
225
228
  *
226
229
  * @example
227
230
  * ```typescript
228
- * // Après un build
229
- * this.notifyUpdate('procedures-stable');
231
+ * // Après un build externe
232
+ * ragManager.notifyUpdate('procedures-stable');
230
233
  *
231
234
  * // Après un rename de document
232
- * this.notifyUpdate('procedures-stable', {
235
+ * ragManager.notifyUpdate('procedures-stable', {
233
236
  * action: 'rename',
234
237
  * oldFile: 'old.md',
235
238
  * newFile: 'new.md'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentic-api",
3
- "version": "2.0.585",
3
+ "version": "2.0.636",
4
4
  "description": "API pour l'orchestration d'agents intelligents avec séquences et escalades automatiques",
5
5
  "main": "dist/src/index.js",
6
6
  "types": "dist/src/index.d.ts",