wingbot 3.76.12 → 3.76.14

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/index.js CHANGED
@@ -25,6 +25,7 @@ const Plugins = require('./src/Plugins');
25
25
  const NotificationsStorage = require('./src/notifications/NotificationsStorage');
26
26
  const Notifications = require('./src/notifications/Notifications');
27
27
  const MemoryBotConfigStorage = require('./src/tools/MemoryBotConfigStorage');
28
+ const MemoryChatLogStorage = require('./src/tools/MemoryChatLogStorage');
28
29
  const routeToEvents = require('./src/tools/routeToEvents');
29
30
  const GraphApi = require('./src/graphApi/GraphApi');
30
31
  const validateBotApi = require('./src/graphApi/validateBotApi');
@@ -91,6 +92,7 @@ module.exports = {
91
92
  bufferloader,
92
93
  asserts,
93
94
  MemoryStateStorage,
95
+ MemoryChatLogStorage,
94
96
  CallbackAuditLog,
95
97
  MemoryBotConfigStorage,
96
98
  CachedModel,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wingbot",
3
- "version": "3.76.12",
3
+ "version": "3.76.14",
4
4
  "description": "Enterprise Messaging Bot Conversation Engine",
5
5
  "main": "index.js",
6
6
  "type": "commonjs",
@@ -43,7 +43,8 @@
43
43
  "cpy-cli": "^5.0.0",
44
44
  "eslint": "^8.56.0",
45
45
  "eslint-config-airbnb": "^19.0.4",
46
- "eslint-plugin-import": "^2.29.1",
46
+ "eslint-import-resolver-node": "^0.4.0",
47
+ "eslint-plugin-import": "^2.32.0",
47
48
  "eslint-plugin-jsdoc": "^48.0.2",
48
49
  "eslint-plugin-jsx-a11y": "^6.8.0",
49
50
  "eslint-plugin-mocha": "^10.2.0",
@@ -69,11 +70,15 @@
69
70
  "jsonwebtoken": "^9.0.2",
70
71
  "node-fetch": "^2.6.7",
71
72
  "path-to-regexp": "^6.3.0",
72
- "uuid": "^9.0.1",
73
+ "uuid": "^14.0.2",
73
74
  "webalize": "^0.1.0"
74
75
  },
75
76
  "optionalDependencies": {
76
77
  "axios": "^1.6.4",
77
78
  "handlebars": "^4.0.0"
79
+ },
80
+ "allowScripts": {
81
+ "fsevents@2.3.2": true,
82
+ "mongodb-memory-server@11.0.1": true
78
83
  }
79
- }
84
+ }
package/src/ChatGpt.js CHANGED
@@ -14,6 +14,7 @@ const LLM = require('./LLM');
14
14
  /** @typedef {import('./Responder').QuickReply} QuickReply */
15
15
  /** @typedef {import('./LLM').LLMMessage} LLMMessage */
16
16
  /** @typedef {import('./LLM').LLMProviderOptions} LLMProviderOptions */
17
+ /** @typedef {import('./LLM').LLMUsage} LLMUsage */
17
18
  /** @typedef {import('./LLMSession').ToolFunction} ToolFunction */
18
19
  /** @typedef {import('./LLMSession').JsonSchemaProp} SimpleJsonSchema */
19
20
 
@@ -285,10 +286,13 @@ class ChatGpt {
285
286
  * @param {LLMMessage[]} prompt
286
287
  * @param {LLMProviderOptions} [options]
287
288
  * @param {ToolFunction[]} [tools=[]]
289
+ * @param {LLMUsage} [usage] - gets filled with the reported token usage
288
290
  * @returns {Promise<LLMMessage>}
289
291
  */
290
- async requestChat (prompt, options, tools = []) {
291
- const choice = await this._request(prompt, options, tools);
292
+ async requestChat (prompt, options, tools = [], usage = {}) {
293
+ const { choice, usage: reportedUsage } = await this._request(prompt, options, tools);
294
+
295
+ Object.assign(usage, reportedUsage);
292
296
 
293
297
  const { finish_reason: finishReason, message } = choice;
294
298
 
@@ -310,7 +314,7 @@ class ChatGpt {
310
314
  * @param {LLMMessage[]} chat
311
315
  * @param {LLMProviderOptions} requestOptions
312
316
  * @param {ToolFunction[]} [tools=[]]
313
- * @returns {Promise<ChatGPTChoice>}
317
+ * @returns {Promise<{choice:ChatGPTChoice, usage:LLMUsage}>}
314
318
  */
315
319
  async _request (chat, requestOptions, tools = []) {
316
320
  const {
@@ -485,11 +489,28 @@ class ChatGpt {
485
489
 
486
490
  const [choice] = responseData.choices;
487
491
 
492
+ const { usage = {}, model: usedModel } = responseData;
493
+ const {
494
+ prompt_tokens: promptTokens,
495
+ completion_tokens: completionTokens,
496
+ prompt_tokens_details: promptDetails = {},
497
+ completion_tokens_details: completionDetails = {}
498
+ } = usage;
499
+
500
+ /** @type {LLMUsage} */
501
+ const llmUsage = {
502
+ model: usedModel,
503
+ promptTokens,
504
+ completionTokens,
505
+ cachedTokens: promptDetails.cached_tokens,
506
+ reasoningTokens: completionDetails.reasoning_tokens
507
+ };
508
+
488
509
  const durationMs = Date.now() - startTime;
489
510
 
490
511
  this._log('#GPT response', { choice, responseData, durationMs });
491
512
 
492
- return choice;
513
+ return { choice, usage: llmUsage };
493
514
  } catch (e) {
494
515
  this._logger.log('#GPT failed', {
495
516
  message: e.message, body, responseText, responseData, status, statusText
@@ -516,7 +537,9 @@ class ChatGpt {
516
537
  { role: 'user', content }
517
538
  ];
518
539
 
519
- return this._request(messages, requestOptions);
540
+ const { choice } = await this._request(messages, requestOptions);
541
+
542
+ return choice;
520
543
  }
521
544
 
522
545
  /**
package/src/LLM.js CHANGED
@@ -88,6 +88,7 @@ const LLMSession = require('./LLMSession');
88
88
  * @param {LLMMessage[]} prompt
89
89
  * @param {LLMProviderOptions} [options]
90
90
  * @param {ToolFunction[]} [tools]
91
+ * @param {LLMUsage} [usage] - gets filled with the reported token usage
91
92
  * @returns {Promise<LLMMessage>}
92
93
  */
93
94
 
@@ -158,6 +159,15 @@ const LLMSession = require('./LLMSession');
158
159
  * @prop {RegExp} regex
159
160
  */
160
161
 
162
+ /**
163
+ * @typedef {object} LLMUsage
164
+ * @prop {string} [model]
165
+ * @prop {number} [promptTokens]
166
+ * @prop {number} [cachedTokens]
167
+ * @prop {number} [completionTokens]
168
+ * @prop {number} [reasoningTokens]
169
+ */
170
+
161
171
  /**
162
172
  * @typedef {object} PromptInfo
163
173
  * @prop {LLMMessage[]} prompt
@@ -167,6 +177,7 @@ const LLMSession = require('./LLMSession');
167
177
  * @prop {number} [durationMs]
168
178
  * @prop {LLMCallOptions} [options]
169
179
  * @prop {string} [error]
180
+ * @prop {LLMUsage} [usage]
170
181
  */
171
182
 
172
183
  /**
@@ -443,8 +454,10 @@ class LLM {
443
454
  const startTime = Date.now();
444
455
  let result = null;
445
456
  let error = null;
457
+ /** @type {LLMUsage} */
458
+ const usage = {};
446
459
  try {
447
- result = await this._provider.requestChat(prompt, opts, session.tools);
460
+ result = await this._provider.requestChat(prompt, opts, session.tools, usage);
448
461
  } catch (e) {
449
462
  error = e;
450
463
  }
@@ -456,7 +469,8 @@ class LLM {
456
469
  session.tools,
457
470
  durationMs,
458
471
  opts,
459
- error
472
+ error,
473
+ Object.keys(usage).length ? usage : null
460
474
  );
461
475
  if (error) throw error;
462
476
  return result;
@@ -471,8 +485,9 @@ class LLM {
471
485
  * @param {number} [durationMs]
472
486
  * @param {LLMCallOptions} [options]
473
487
  * @param {Error} [error]
488
+ * @param {LLMUsage} [usage]
474
489
  */
475
- logPrompt (prompt, result, vectorSearchResult, tools, durationMs, options, error) {
490
+ logPrompt (prompt, result, vectorSearchResult, tools, durationMs, options, error, usage) {
476
491
  this._lastResult = result;
477
492
  this._configuration.logger.logPrompt({
478
493
  prompt,
@@ -481,6 +496,7 @@ class LLM {
481
496
  tools,
482
497
  durationMs,
483
498
  ...(options != null && { options }),
499
+ ...(usage != null && { usage }),
484
500
  ...(error != null && { error: error?.message || String(error) })
485
501
  });
486
502
  }
@@ -129,6 +129,14 @@ type ToolFunction {
129
129
  parameters: Any
130
130
  }
131
131
 
132
+ type LLMUsage {
133
+ model: String
134
+ promptTokens: Float
135
+ cachedTokens: Float
136
+ completionTokens: Float
137
+ reasoningTokens: Float
138
+ }
139
+
132
140
  type PromptInfo {
133
141
  prompt: [LLMMessage!]!
134
142
  result: LLMMessage
@@ -137,6 +145,7 @@ type PromptInfo {
137
145
  durationMs: Float
138
146
  options: Any
139
147
  error: String
148
+ usage: LLMUsage
140
149
  }
141
150
 
142
151
  type UserInteraction {
@@ -3,8 +3,6 @@
3
3
  */
4
4
  'use strict';
5
5
 
6
- const uuid = require('uuid');
7
-
8
6
  /**
9
7
  * @typedef {object} Tag
10
8
  * @prop {string} tag
@@ -120,7 +118,7 @@ class NotificationsStorage {
120
118
  * @param {object} tasks
121
119
  * @returns {Promise<Task[]>}
122
120
  */
123
- pushTasks (tasks) {
121
+ async pushTasks (tasks) {
124
122
 
125
123
  // upsert through unique KEY (only single sliding campaign in queue)
126
124
  // [campaignId,senderId,pageId,sent]
@@ -152,6 +150,9 @@ class NotificationsStorage {
152
150
  return override;
153
151
  });
154
152
 
153
+ // eslint-disable-next-line import/no-unresolved
154
+ const uuid = await import('uuid');
155
+
155
156
  const insert = tasks.map((t) => ({
156
157
  ...t,
157
158
  id: uuid.v4(),
@@ -162,7 +163,7 @@ class NotificationsStorage {
162
163
  this._tasks.push(...insert);
163
164
 
164
165
  this._tasks.sort((a, b) => a.enqueue - b.enqueue);
165
- return Promise.resolve(ret);
166
+ return ret;
166
167
  }
167
168
 
168
169
  popTasks (limit, until = Date.now()) {
@@ -306,6 +307,8 @@ class NotificationsStorage {
306
307
  async upsertCampaign (campaign, updateCampaign = null) {
307
308
  let insert = campaign;
308
309
  if (!insert.id) {
310
+ // eslint-disable-next-line import/no-unresolved
311
+ const uuid = await import('uuid');
309
312
  insert = { ...insert, id: uuid.v4() };
310
313
  }
311
314
  if (!this._campaigns.has(insert.id)) {