wingbot 3.75.9-alpha.2 → 3.75.9-alpha.4

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/jsconfig.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "compilerOptions": {
3
3
  "module": "commonjs",
4
- "lib": ["es2019", "es2020.promise", "es2020.bigint", "es2020.string", "dom"],
4
+ "lib": ["es2019", "es2020.promise", "es2020.bigint", "es2020.string", "es2022.error", "dom"],
5
5
  "target": "ESNext",
6
6
  "allowSyntheticDefaultImports": true,
7
7
  "checkJs": true,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wingbot",
3
- "version": "3.75.9-alpha.2",
3
+ "version": "3.75.9-alpha.4",
4
4
  "description": "Enterprise Messaging Bot Conversation Engine",
5
5
  "main": "index.js",
6
6
  "type": "commonjs",
package/src/ChatGpt.js CHANGED
@@ -373,7 +373,8 @@ class ChatGpt {
373
373
  type: 'json_schema',
374
374
  json_schema: {
375
375
  name,
376
- schema
376
+ schema,
377
+ strict: true
377
378
  }
378
379
  };
379
380
  } else if (typeof responseFormat === 'string') {
@@ -166,20 +166,44 @@ class GlobalIntents {
166
166
  id, matcher = null, action: intentPath, local, title,
167
167
  entitiesSetState = {}, usedEntities, meta = {},
168
168
  classification = null, router = null,
169
- keepUserInInteractionsWithBounceAllowed
170
-
169
+ keepUserInInteractionsWithBounceAllowed,
170
+ localPath: prevLocalPath
171
171
  } = gi;
172
172
  const action = intentPath === '/*'
173
173
  ? pathContext.path
174
174
  : `${pathContext.path}${intentPath}`.replace(/^\/\*/, '');
175
175
 
176
+ let localPath;
177
+
178
+ if (prevLocalPath === '/') {
179
+ localPath = `${pathContext.path}`;
180
+ } else if (prevLocalPath) {
181
+ localPath = `${pathContext.path}${prevLocalPath}`;
182
+ } else {
183
+ localPath = action === pathContext.path
184
+ ? action.replace(/\/[^/]+$/, '')
185
+ : pathContext.path.replace(/\/[^/]+$/, '');
186
+
187
+ if (!localPath) {
188
+ localPath = '/';
189
+ }
190
+ }
191
+
192
+ // console.log('merge', {
193
+ // action,
194
+ // pathContextPath: pathContext.path,
195
+ // intentPath,
196
+ // prevLocalPath,
197
+ // localPath
198
+ // });
199
+
176
200
  target.set(id, {
177
201
  id,
178
202
  matcher,
179
203
  usedEntities,
180
204
  entitiesSetState,
181
205
  action,
182
- localPath: pathContext.path,
206
+ localPath,
183
207
  local,
184
208
  title,
185
209
  classification,
@@ -496,8 +496,10 @@ class LLMDispatcher {
496
496
  }
497
497
  }
498
498
 
499
+ const llmRouting = LLMRouter.prepareRouting(globalIntents);
500
+
499
501
  return {
500
- ...LLMRouter.prepareRouting(globalIntents),
502
+ ...llmRouting,
501
503
  nlpMatchers: Array.from(giMatchersByAction.values()),
502
504
  giByAction
503
505
  };
package/src/LLMRouter.js CHANGED
@@ -143,7 +143,7 @@ class LLMRouter {
143
143
  .object({
144
144
  action: LLMType.string()
145
145
  .description('recommended action')
146
- }, 'conversation routing information')
146
+ }, 'conversation_routing_information')
147
147
  .toJSON();
148
148
  }
149
149
  return LLMRouter._cachedStructuredOutput;
@@ -159,12 +159,34 @@ class LLMRouter {
159
159
  static defaultRoute (prompt) {
160
160
  /** @type {RouterResolver} */
161
161
  const route = async (llm, req, routing) => {
162
- const res = await llm.session('routing')
162
+ const session = llm.session('routing')
163
163
  .setData(routing)
164
- .systemPrompt(prompt)
165
- .generateStructured(LLMRouter.structuredOutput());
164
+ .systemPrompt(prompt);
166
165
 
167
- if (!routing.byAction.has(LLMRouter._normByAction(res.action))) {
166
+ const userText = typeof req?.text === 'function' ? req.text() : null;
167
+ if (userText) {
168
+ session.user(userText);
169
+ }
170
+
171
+ let res;
172
+ try {
173
+ res = await session.generateStructured(LLMRouter.structuredOutput());
174
+ } catch (e) {
175
+ // Fail closed: any error in routing classification is treated
176
+ // as "no context change" so the user's current flow continues.
177
+ // Surfaces to Sentry via the host-configured logger.
178
+ llm.log.error('LLMRouter classification failed', e, {
179
+ // userText,
180
+ candidateActions: routing?.byAction
181
+ ? Array.from(routing.byAction.keys())
182
+ : [],
183
+ senderId: req?.senderId ?? null,
184
+ pageId: req?.pageId ?? null
185
+ });
186
+ return null;
187
+ }
188
+
189
+ if (!res || !routing.byAction.has(LLMRouter._normByAction(res.action))) {
168
190
  return null;
169
191
  }
170
192
 
@@ -226,6 +248,10 @@ class LLMRouter {
226
248
  });
227
249
  }
228
250
 
251
+ /**
252
+ * @param {string} act
253
+ * @returns {string}
254
+ */
229
255
  static _normByAction (act) {
230
256
  return act.replace(/^\/|\/$/g, '');
231
257
  }
package/src/LLMSession.js CHANGED
@@ -842,7 +842,14 @@ class LLMSession {
842
842
  responseFormat
843
843
  }, logOptions);
844
844
 
845
- return JSON.parse(result.content);
845
+ try {
846
+ return JSON.parse(result.content);
847
+ } catch (e) {
848
+ throw new Error(
849
+ `LLM structured output is not valid JSON: ${e.message}. Raw content: ${JSON.stringify(result.content)}`,
850
+ { cause: e }
851
+ );
852
+ }
846
853
  });
847
854
  return this;
848
855
  }
@@ -1,10 +0,0 @@
1
- {
2
- "permissions": {
3
- "allow": [
4
- "Bash(npx mocha:*)",
5
- "Bash(npx tsc *)",
6
- "Bash(npm test *)",
7
- "Bash(node -e \"const p = require\\('./bot/plugins/BTMLLM'\\); console.log\\('factory type:', typeof p\\); console.log\\('factory name:', p.name\\);\")"
8
- ]
9
- }
10
- }