@peopl-health/nexus 3.1.4 → 3.1.6

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.
@@ -483,6 +483,8 @@ class NexusMessaging {
483
483
  const result = await this._processMessages(from, () => replyAssistant(from, body));
484
484
  const response = typeof result === 'string' ? result : result?.output;
485
485
  const tools_executed = typeof result === 'object' ? result?.tools_executed : undefined;
486
+ const prompt = typeof result === 'object' ? result?.prompt : undefined;
487
+ const response_id = typeof result === 'object' ? result?.response_id : undefined;
486
488
 
487
489
  if (response) {
488
490
  await this.sendMessage({
@@ -490,7 +492,9 @@ class NexusMessaging {
490
492
  body: response,
491
493
  processed: true,
492
494
  origin: 'assistant',
493
- tools_executed
495
+ tools_executed,
496
+ prompt,
497
+ response_id
494
498
  });
495
499
  }
496
500
  } catch (error) {
@@ -550,6 +554,8 @@ class NexusMessaging {
550
554
  const result = await this._processMessages(from, () => replyAssistant(from, fallbackMessage));
551
555
  const response = typeof result === 'string' ? result : result?.output;
552
556
  const tools_executed = typeof result === 'object' ? result?.tools_executed : undefined;
557
+ const prompt = typeof result === 'object' ? result?.prompt : undefined;
558
+ const response_id = typeof result === 'object' ? result?.response_id : undefined;
553
559
 
554
560
  if (response) {
555
561
  await this.sendMessage({
@@ -557,7 +563,9 @@ class NexusMessaging {
557
563
  body: response,
558
564
  processed: true,
559
565
  origin: 'assistant',
560
- tools_executed
566
+ tools_executed,
567
+ prompt,
568
+ response_id
561
569
  });
562
570
  }
563
571
  } catch (error) {
@@ -728,6 +736,8 @@ class NexusMessaging {
728
736
 
729
737
  const botResponse = typeof result === 'string' ? result : result?.output;
730
738
  const tools_executed = typeof result === 'object' ? result?.tools_executed : undefined;
739
+ const prompt = typeof result === 'object' ? result?.prompt : undefined;
740
+ const response_id = typeof result === 'object' ? result?.response_id : undefined;
731
741
 
732
742
  if (typingInterval) {
733
743
  clearInterval(typingInterval);
@@ -741,7 +751,9 @@ class NexusMessaging {
741
751
  body: botResponse,
742
752
  processed: true,
743
753
  origin: 'assistant',
744
- tools_executed
754
+ tools_executed,
755
+ prompt,
756
+ response_id
745
757
  });
746
758
  }
747
759
 
@@ -73,7 +73,9 @@ const messageSchema = new mongoose.Schema({
73
73
  errorCode: { type: String, default: null },
74
74
  errorMessage: { type: String, default: null },
75
75
  updatedAt: { type: Date, default: null }
76
- }
76
+ },
77
+ prompt: { type: Object, default: null },
78
+ response_id: { type: String, default: null }
77
79
  }, { timestamps: true });
78
80
 
79
81
  messageSchema.index({ numero: 1, createdAt: -1 });
@@ -12,6 +12,7 @@ const threadSchema = new mongoose.Schema({
12
12
  active: { type: Boolean, default: true },
13
13
  stopped: { type: Boolean, default: false },
14
14
  review: { type: Boolean, default: false },
15
+ version: { type: Number, default: null },
15
16
  nextSid: { type: [String], default: [] }
16
17
  }, { timestamps: true });
17
18
 
@@ -175,10 +175,12 @@ class OpenAIResponsesProvider {
175
175
  */
176
176
  async executeRun({ thread, assistant, tools = [], config = {} }) {
177
177
  const { conversationId, assistantId } = this._normalizeThread(thread);
178
+ const promptVersion = thread?.version || null;
178
179
 
179
180
  logger.info('[OpenAIResponsesProvider] Starting run', {
180
181
  conversationId,
181
- assistantId
182
+ assistantId,
183
+ promptVersion
182
184
  });
183
185
 
184
186
  try {
@@ -219,6 +221,7 @@ class OpenAIResponsesProvider {
219
221
  tools,
220
222
  context,
221
223
  promptVariables,
224
+ promptVersion,
222
225
  assistant,
223
226
  ...config
224
227
  });
@@ -275,7 +278,8 @@ class OpenAIResponsesProvider {
275
278
  model,
276
279
  assistant,
277
280
  toolMetadata,
278
- promptVariables = null,
281
+ promptVersion = null,
282
+ promptVariables = null
279
283
  } = {}) {
280
284
  try {
281
285
  const id = this._ensurethreadId(threadId);
@@ -286,9 +290,9 @@ class OpenAIResponsesProvider {
286
290
 
287
291
  input = input.filter(item => item.type !== 'function_call' && item.type !== 'function_call_output');
288
292
 
289
- const promptConfig = promptVariables
290
- ? { id: assistantId, variables: promptVariables }
291
- : { id: assistantId };
293
+ const promptConfig = { id: assistantId };
294
+ if (promptVariables) promptConfig.variables = promptVariables;
295
+ if (promptVersion) promptConfig.version = promptVersion;
292
296
  logger.info('[OpenAIResponsesProvider] Prompt config', { promptConfig });
293
297
 
294
298
  const makeAPICall = (inputData) => retryWithBackoff(() =>
@@ -232,6 +232,8 @@ const replyAssistantCore = async (code, message_ = null, thread_ = null, runOpti
232
232
  timings.total_ms = Date.now() - startTotal;
233
233
 
234
234
  const { output: rawOutput, completed, retries, predictionTimeMs, tools_executed } = runResult;
235
+ const prompt = runResult.run?.prompt || null;
236
+ const response_id = runResult.run?.id || null;
235
237
 
236
238
  const output = sanitizeOutput(rawOutput);
237
239
  if (rawOutput !== output) {
@@ -269,7 +271,7 @@ const replyAssistantCore = async (code, message_ = null, thread_ = null, runOpti
269
271
  }).catch(err => logger.error('[replyAssistantCore] Failed to store metrics', { error: err.message }));
270
272
  }
271
273
 
272
- return { output, tools_executed };
274
+ return { output, tools_executed, prompt, response_id };
273
275
  } catch (error) {
274
276
  logger.error('[replyAssistantCore] Error in reply', {
275
277
  error: error.message,
@@ -157,6 +157,8 @@ class MongoStorage {
157
157
  raw: messageData.raw || null,
158
158
  origin: messageData.origin || 'whatsapp_platform',
159
159
  tools_executed: messageData.tools_executed,
160
+ prompt: messageData.prompt || null,
161
+ response_id: messageData.response_id || null,
160
162
  statusInfo
161
163
  };
162
164
  }
@@ -7,17 +7,43 @@ function removeBracketContent(text) {
7
7
  return text.replace(/\[([^\]]*)\]/g, '').trim();
8
8
  }
9
9
 
10
+ function formatForWhatsApp(text) {
11
+ if (!text || typeof text !== 'string') return text;
12
+
13
+ let formatted = text;
14
+
15
+ // Add line breaks after dash items (bullet points)
16
+ formatted = formatted.replace(/(\.\s*-\s+)/g, '.\n\n- ');
17
+ formatted = formatted.replace(/(:)\s*(-\s+)/g, '$1\n- ');
18
+
19
+ // Add line breaks after semicolons when they separate items
20
+ formatted = formatted.replace(/;\s*-\s+/g, ';\n- ');
21
+
22
+ // Add line breaks after periods that end sentences before dashes
23
+ formatted = formatted.replace(/(\.\s+)(-\s+)/g, '$1\n$2');
24
+
25
+ // Convert dashes to bullet points
26
+ formatted = formatted.replace(/^-\s+/gm, '• ');
27
+ formatted = formatted.replace(/(\n|^)\s*-\s+/g, '$1• ');
28
+
29
+ // Clean up multiple consecutive line breaks
30
+ formatted = formatted.replace(/\n{3,}/g, '\n\n');
31
+
32
+ return formatted.trim();
33
+ }
34
+
10
35
  function sanitizeOutput(text) {
11
36
  if (!text || typeof text !== 'string') return text;
12
37
 
13
38
  let sanitized = text;
14
39
  sanitized = removeBracketContent(sanitized);
15
- sanitized = sanitized.replace(/\s+/g, ' ').trim();
40
+ sanitized = formatForWhatsApp(sanitized);
16
41
 
17
42
  return sanitized;
18
43
  }
19
44
 
20
45
  module.exports = {
21
46
  sanitizeOutput,
22
- removeBracketContent
47
+ removeBracketContent,
48
+ formatForWhatsApp
23
49
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@peopl-health/nexus",
3
- "version": "3.1.4",
3
+ "version": "3.1.6",
4
4
  "description": "Core messaging and assistant library for WhatsApp communication platforms",
5
5
  "keywords": [
6
6
  "whatsapp",