@scout9/app 1.0.0-alpha.0.8.9 → 1.0.0-alpha.0.9.1
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/dist/{_rollupPluginBabelHelpers-606d8129.cjs → _rollupPluginBabelHelpers-9c73c95c.cjs} +98 -0
- package/dist/{dev-c58715b1.cjs → dev-9a3ac888.cjs} +3 -3
- package/dist/{index-9c237a7b.cjs → index-426210e7.cjs} +7 -7
- package/dist/index.cjs +4 -4
- package/dist/{macros-9ad79144.cjs → macros-77983cef.cjs} +1 -1
- package/dist/{multipart-parser-ec335b80.cjs → multipart-parser-8936e98f.cjs} +4 -4
- package/dist/schemas.cjs +2 -2
- package/dist/spirits.cjs +256 -201
- package/dist/testing-tools.cjs +3 -3
- package/package.json +1 -1
- package/src/testing-tools/spirits.js +72 -10
package/dist/testing-tools.cjs
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
-
var dev = require("./dev-
|
|
6
|
-
require("./_rollupPluginBabelHelpers-
|
|
5
|
+
var dev = require("./dev-9a3ac888.cjs");
|
|
6
|
+
require("./_rollupPluginBabelHelpers-9c73c95c.cjs");
|
|
7
7
|
require('util');
|
|
8
8
|
require('stream');
|
|
9
9
|
require('path');
|
|
@@ -24,7 +24,7 @@ require('node:url');
|
|
|
24
24
|
require('node:events');
|
|
25
25
|
require('node:stream');
|
|
26
26
|
require('node:string_decoder');
|
|
27
|
-
require("./macros-
|
|
27
|
+
require("./macros-77983cef.cjs");
|
|
28
28
|
require('node:readline');
|
|
29
29
|
require('node:process');
|
|
30
30
|
require('node:os');
|
package/package.json
CHANGED
|
@@ -104,6 +104,40 @@
|
|
|
104
104
|
*/
|
|
105
105
|
|
|
106
106
|
|
|
107
|
+
class SpiritError extends Error {
|
|
108
|
+
/**
|
|
109
|
+
* @param {string} message - Description of the error.
|
|
110
|
+
* @param {string} step - The step or phase in which the error occurred.
|
|
111
|
+
*/
|
|
112
|
+
constructor(message, step) {
|
|
113
|
+
super(message);
|
|
114
|
+
this.name = this.constructor.name;
|
|
115
|
+
this.step = step;
|
|
116
|
+
|
|
117
|
+
// Ensures the stack trace starts from where this error was created
|
|
118
|
+
if (Error.captureStackTrace) {
|
|
119
|
+
Error.captureStackTrace(this, this.constructor);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
*
|
|
125
|
+
* @param {unknown} err
|
|
126
|
+
* @param {string} step
|
|
127
|
+
* @returns {SpiritError}
|
|
128
|
+
*/
|
|
129
|
+
static fromError(err, step) {
|
|
130
|
+
if (err instanceof SpiritError) return err;
|
|
131
|
+
if (err instanceof Error) {
|
|
132
|
+
const wrapped = new SpiritError(err.message, step, { cause: err });
|
|
133
|
+
wrapped.stack = err.stack;
|
|
134
|
+
return wrapped;
|
|
135
|
+
}
|
|
136
|
+
// fallback for non-Error values
|
|
137
|
+
return new SpiritError(String(err), step);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
107
141
|
/**
|
|
108
142
|
* @typedef {Object} ConversationEvent
|
|
109
143
|
* @property {(Change<import('@scout9/app').Conversation> & {
|
|
@@ -258,6 +292,25 @@ export const Spirits = {
|
|
|
258
292
|
}
|
|
259
293
|
};
|
|
260
294
|
|
|
295
|
+
const onStatus = (statusType, completeOrError = true) => {
|
|
296
|
+
progress(`${statusType}: ${completeOrError}`, 'info', 'STATUS', {[statusType]: completeOrError});
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* @param {Promise<any>} prom
|
|
301
|
+
* @param {string} step
|
|
302
|
+
*/
|
|
303
|
+
const wrapStep = async (prom, step) => {
|
|
304
|
+
try {
|
|
305
|
+
const result = await prom;
|
|
306
|
+
onStatus(step);
|
|
307
|
+
return result;
|
|
308
|
+
} catch (error) {
|
|
309
|
+
onStatus(step, error.message || 'UNHANDLED ERROR');
|
|
310
|
+
throw SpiritError.fromError(error, step);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
|
|
261
314
|
// 1. Check inputs
|
|
262
315
|
if (!conversation.$agent) {
|
|
263
316
|
throw new Error(`SpiritsError: No agent found in conversation, must define ".$agent" in the conversation`);
|
|
@@ -284,7 +337,8 @@ export const Spirits = {
|
|
|
284
337
|
|
|
285
338
|
// 2. Parse the message
|
|
286
339
|
progress('Parsing message', 'info', 'SET_PROCESSING', 'user');
|
|
287
|
-
const parsePayload = await parser(message.content, 'en');
|
|
340
|
+
const parsePayload = await wrapStep(parser(message.content, 'en'), 'parse');
|
|
341
|
+
|
|
288
342
|
if (parsePayload.intent) {
|
|
289
343
|
message.intent = parsePayload.intent;
|
|
290
344
|
}
|
|
@@ -370,7 +424,7 @@ export const Spirits = {
|
|
|
370
424
|
|
|
371
425
|
// 3. Run the contextualizer
|
|
372
426
|
progress('Running contextualizer', 'info', 'SET_PROCESSING', 'system');
|
|
373
|
-
const newContextMessages = await contextualizer({ conversation, messages });
|
|
427
|
+
const newContextMessages = await wrapStep(contextualizer({ conversation, messages }), 'contextualize');
|
|
374
428
|
for (const contextMessage of newContextMessages) {
|
|
375
429
|
if (!messages.find(mes => mes.content === contextMessage.content)) {
|
|
376
430
|
messages.push(contextMessage);
|
|
@@ -383,7 +437,7 @@ export const Spirits = {
|
|
|
383
437
|
// 4. Run the workflow
|
|
384
438
|
progress('Running workflow', 'info', 'SET_PROCESSING', 'system');
|
|
385
439
|
|
|
386
|
-
const slots = await workflow({
|
|
440
|
+
const slots = await wrapStep(workflow({
|
|
387
441
|
messages,
|
|
388
442
|
conversation,
|
|
389
443
|
context,
|
|
@@ -396,7 +450,7 @@ export const Spirits = {
|
|
|
396
450
|
initial: conversation.intent || null
|
|
397
451
|
},
|
|
398
452
|
stagnationCount: conversation.lockAttempts || 0
|
|
399
|
-
})
|
|
453
|
+
}), 'workflow')
|
|
400
454
|
.then((res) => Array.isArray(res) ? res : [res])
|
|
401
455
|
.then((slots) => slots.reduce((accumulator, slot) => {
|
|
402
456
|
if ('toJSON' in slot) {
|
|
@@ -646,7 +700,7 @@ export const Spirits = {
|
|
|
646
700
|
if (!!_tasks && Array.isArray(_tasks) && !!_tasks.length) {
|
|
647
701
|
generatorInput.tasks = _tasks;
|
|
648
702
|
}
|
|
649
|
-
const generatorPayload = await generator(generatorInput);
|
|
703
|
+
const generatorPayload = await wrapStep(generator(generatorInput), 'generate');
|
|
650
704
|
if (!generatorPayload.send) {
|
|
651
705
|
progress(
|
|
652
706
|
'Generated response',
|
|
@@ -710,10 +764,12 @@ export const Spirits = {
|
|
|
710
764
|
// De-dupe by content (change the key if you want stricter uniqueness)
|
|
711
765
|
.reduce(
|
|
712
766
|
(acc, msg) => {
|
|
713
|
-
const key = String(msg.content); // e.g. `${msg.role}::${msg.content}` for stronger uniqueness
|
|
767
|
+
const key = String(msg.content || msg.tool_calls ? JSON.stringify(msg.tool_calls) : ''); // e.g. `${msg.role}::${msg.content}` for stronger uniqueness
|
|
714
768
|
if (!acc.seen.has(key)) {
|
|
715
769
|
acc.seen.add(key);
|
|
716
770
|
acc.items.push(msg);
|
|
771
|
+
} else {
|
|
772
|
+
console.warn(`Duplicate message removed: ${JSON.stringify(msg)}`);
|
|
717
773
|
}
|
|
718
774
|
return acc;
|
|
719
775
|
},
|
|
@@ -749,18 +805,20 @@ export const Spirits = {
|
|
|
749
805
|
console.error(`Spirits: Locking conversation, error generating response: ${e.message}`);
|
|
750
806
|
conversation = lockConversation(conversation, 'API: ' + e.message);
|
|
751
807
|
}
|
|
808
|
+
} else {
|
|
809
|
+
onStatus('generate', 'ignored');
|
|
752
810
|
}
|
|
753
811
|
|
|
754
812
|
if (messagesToTransform.length && transformer) {
|
|
755
813
|
try {
|
|
756
|
-
for (const messageToTransform of messagesToTransform) {
|
|
757
|
-
const transformResponse = await transformer({
|
|
814
|
+
// for (const messageToTransform of messagesToTransform) {
|
|
815
|
+
const transformResponse = await wrapStep(transformer({
|
|
758
816
|
message: messagesToTransform,
|
|
759
817
|
persona,
|
|
760
818
|
customer: customer.id,
|
|
761
819
|
messages,
|
|
762
820
|
context: context
|
|
763
|
-
});
|
|
821
|
+
}), 'transform');
|
|
764
822
|
|
|
765
823
|
progress('Generated response', 'success', undefined, undefined);
|
|
766
824
|
// Check if already had message
|
|
@@ -779,7 +837,7 @@ export const Spirits = {
|
|
|
779
837
|
progress('Added agent message', 'info', 'ADD_MESSAGE', messages[messages.length - 1]);
|
|
780
838
|
}
|
|
781
839
|
|
|
782
|
-
}
|
|
840
|
+
// }
|
|
783
841
|
} catch (e) {
|
|
784
842
|
console.error(`Locking conversation, error transforming response: ${e.message}`);
|
|
785
843
|
conversation = lockConversation(conversation, 'API: ' + e.message);
|
|
@@ -787,7 +845,11 @@ export const Spirits = {
|
|
|
787
845
|
}
|
|
788
846
|
} else if (messagesToTransform.length) {
|
|
789
847
|
console.warn(`No transformer provided`);
|
|
848
|
+
onStatus('transform', 'ignored');
|
|
790
849
|
}
|
|
850
|
+
} else {
|
|
851
|
+
onStatus('generate', 'ignored');
|
|
852
|
+
onStatus('transform', 'ignored');
|
|
791
853
|
}
|
|
792
854
|
|
|
793
855
|
progress('Parsing message', 'info', 'SET_PROCESSING', null);
|