jsfe 1.14.0 → 1.14.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/forms/choice-flow.js +2 -2
- package/dist/forms/flows.d.ts.map +1 -1
- package/dist/forms/flows.js +5 -4
- package/dist/forms/identity-flows.js +2 -2
- package/dist/helpers/contact.d.ts.map +1 -1
- package/dist/helpers/contact.js +4 -1
- package/dist/host/reply-rank.d.ts +3 -1
- package/dist/host/reply-rank.d.ts.map +1 -1
- package/dist/host/reply-rank.js +6 -2
- package/dist/runtime-identity.js +1 -1
- package/package.json +1 -1
|
@@ -452,7 +452,7 @@ export const FLOWS = [
|
|
|
452
452
|
"id": "ac_switch_to_text_key",
|
|
453
453
|
"type": "SET",
|
|
454
454
|
"variable": "ac_key",
|
|
455
|
-
"value": "ac_key === '' && !ac_other && !ac_amount && cargo.voice && String(ac_answer || '').trim() === '9' && !!callerTextNumber(cargo) ? '__text' : ac_key"
|
|
455
|
+
"value": "ac_key === '' && !ac_other && !ac_amount && cargo.voice && String(ac_answer || '').trim().replace(/[.,!?;:]+$/, '') === '9' && !!callerTextNumber(cargo) ? '__text' : ac_key"
|
|
456
456
|
},
|
|
457
457
|
{
|
|
458
458
|
"id": "ac_keypad_again",
|
|
@@ -629,7 +629,7 @@ export const FLOWS = [
|
|
|
629
629
|
"id": "ac_switch_to_text_key_again",
|
|
630
630
|
"type": "SET",
|
|
631
631
|
"variable": "ac_key",
|
|
632
|
-
"value": "ac_key === '' && !ac_other && !ac_amount && cargo.voice && String(ac_answer || '').trim() === '9' && !!callerTextNumber(cargo) ? '__text' : ac_key"
|
|
632
|
+
"value": "ac_key === '' && !ac_other && !ac_amount && cargo.voice && String(ac_answer || '').trim().replace(/[.,!?;:]+$/, '') === '9' && !!callerTextNumber(cargo) ? '__text' : ac_key"
|
|
633
633
|
},
|
|
634
634
|
{
|
|
635
635
|
"id": "ac_keypad_done",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flows.d.ts","sourceRoot":"","sources":["../../src/forms/flows.js"],"names":[],"mappings":"AA6HA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4DC;AACD;;;GAGG;AACH;;;;;;EAGC;
|
|
1
|
+
{"version":3,"file":"flows.d.ts","sourceRoot":"","sources":["../../src/forms/flows.js"],"names":[],"mappings":"AA6HA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4DC;AACD;;;GAGG;AACH;;;;;;EAGC;AAqdD,wHAAwH;AACxH,wEAaC;AACD,4FAA4F;AAC5F;;;EAYC;AACD,sGAAsG;AACtG;;;EAOC;AAjpBM,6CAAuG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA00B9G;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAOG"}
|
package/dist/forms/flows.js
CHANGED
|
@@ -383,8 +383,9 @@ const readFormResponse = {
|
|
|
383
383
|
};
|
|
384
384
|
// An answer the field's reader could not read goes to the reply ranker, never straight to the host (owner 2026-10-26: a form
|
|
385
385
|
// gives up only for a real new intent). The ranker is offered the question's declared choices and the two escapes every
|
|
386
|
-
// question supports (owner 2026-10-28): a person, and on a call with a textable number, text.
|
|
387
|
-
// exact
|
|
386
|
+
// question supports (owner 2026-10-28): a person, and on a call with a textable number, text. Every declared choice is
|
|
387
|
+
// offered, `exact` ones too (exact is how WORDS match a choice, not a confirmation); only the YES of a firm (hard)
|
|
388
|
+
// confirmation never is. A choice without a label is described by its key and its worded phrases (keys are digits).
|
|
388
389
|
// `answers` (picks none): asked again ("Sorry, I didn't catch that."), counted as an attempt so max_attempts still bounds
|
|
389
390
|
// it; `abort` ends every flow; `new_request` goes to intent detection.
|
|
390
391
|
const rankedMiss = (id) => SIDE(id, "(cargo.forms[form].attempts=cargo.forms[form].attempts || {},cargo.forms[form].attempts[input]=Number(cargo.forms[form].attempts[input] || 0)+1,cargo.forms[form].feedback=cargo.forms[form].feedback || {},cargo.forms[form].feedback[input]='miss',true)");
|
|
@@ -404,11 +405,11 @@ const readFormReply = {
|
|
|
404
405
|
rankedMiss('reply_miss')]
|
|
405
406
|
};
|
|
406
407
|
const readFormChoice = {
|
|
407
|
-
id: 'read-form-choice', name: 'ReadFormChoice', version: '1.
|
|
408
|
+
id: 'read-form-choice', name: 'ReadFormChoice', version: '1.2.0', scope: 'isolated', description: 'Rank an unreadable answer to a choice question and take the offered option it picks, or a request for a person or for text; otherwise ask again. A withdrawal or a new request leaves with saved form progress.',
|
|
408
409
|
parameters: [{ name: 'form', type: 'string' }, { name: 'input', type: 'string' }, { name: 'question', type: 'string' }, { name: 'question_es', type: 'string' }, { name: 'choices', type: 'array' }, { name: 'firm', type: 'string' }],
|
|
409
410
|
variables: vars({ question: '', question_es: '', choices: [], firm: '', asked: '', ranked: [], reply: null, picked: '', chain: null, reading: null }),
|
|
410
411
|
steps: [SET('choice_asked', 'asked', "language === 'es' && question_es ? question_es : question"),
|
|
411
|
-
rankedChoices('choice_ranked', "(choices || []).filter(function(c){return
|
|
412
|
+
rankedChoices('choice_ranked', "(choices || []).filter(function(c){return !(firm==='firm' && String(c.key)==='yes');}).map(function(c){var said=(Array.isArray(c.phrases) ? c.phrases : []).map(String).filter(function(p){return /[a-zà-ÿ]/i.test(p) && p!==String(c.key);}).slice(0,6);return {key:String(c.key),label:String(c.label || (said.length ? c.key+' ('+said.join(', ')+')' : c.key))};})"),
|
|
412
413
|
rankedDispatch('choice_dispatch', 'input_not_matched'),
|
|
413
414
|
...escapeRoutes('choice_escape'),
|
|
414
415
|
SET('choice_picked', 'picked', "(function(){var k=String(reply && reply.key || '');var c=(choices || []).filter(function(c){return String(c.key)===k;})[0];return c ? String(c.key) : '';})()"),
|
|
@@ -257,12 +257,12 @@ const retry = worker('generic-retry-with-options', 'GenericRetryWithOptions', 'C
|
|
|
257
257
|
set('retry_question', 'retry_question', "error_message+' '+(question || 'Would you like to try again?')+' To retry '+(cargo.voice?'Press 1 or ':'')+cargo.verb+' YES. '+(callerTextNumber(cargo)?'To switch to text press 9 or '+cargo.verb+' TEXT. ':'')+'To abort '+(cargo.voice?'press the asterisk key or ':'')+cargo.verb+' EXIT.'"),
|
|
258
258
|
set('retry_question_es', 'retry_question_es', "error_message_es+' '+(question_es || '¿Le gustaría intentar nuevamente?')+' Para reintentar '+(cargo.voice?'Presione 1 o ':'')+cargo.verb_es+' SÍ. '+(callerTextNumber(cargo)?'Para cambiar a texto presione 9 o '+cargo.verb_es+' TEXTO. ':'')+'Para salir '+(cargo.voice?'presione la tecla de asterisco o ':'')+cargo.verb_es+' SALIR.'"),
|
|
259
259
|
call('retry_collect', 'collect-service-answer', { profiles: '{{retry_profiles}}', question: '{{retry_question}}', question_es: '{{retry_question_es}}', keypad: { min: 1, max: 1 }, parent_form: '{{parent_form}}' }),
|
|
260
|
-
set('retry_answer', 'user_choice', 'String(cargo.serviceAnswer.raw || "")'),
|
|
260
|
+
set('retry_answer', 'user_choice', 'String(cargo.serviceAnswer.raw || "").trim().replace(/[.,!?;:]+$/,"")'),
|
|
261
261
|
set('retry_default_cancel', 'cancel_flow', "cancel_flow || 'contact-support'"),
|
|
262
262
|
when('retry_unknown_key_question', '/^\\s*[2-8]\\s*$/.test(user_choice)', set('retry_unknown_question', 'retry_question', "'Sorry, that is not an option. To retry '+(cargo.voice?'Press 1 or ':'')+cargo.verb+' YES. '+(callerTextNumber(cargo)?'To switch to text press 9 or '+cargo.verb+' TEXT. ':'')+(cargo.voice?'For an agent press 0. ':'')+'To abort '+(cargo.voice?'press the asterisk key or ':'')+cargo.verb+' EXIT.'")),
|
|
263
263
|
when('retry_unknown_key_question_es', '/^\\s*[2-8]\\s*$/.test(user_choice)', set('retry_unknown_question_es', 'retry_question_es', "'Lo siento, esa no es una opción. Para reintentar '+(cargo.voice?'Presione 1 o ':'')+cargo.verb_es+' SÍ. '+(callerTextNumber(cargo)?'Para cambiar a texto presione 9 o '+cargo.verb_es+' TEXTO. ':'')+(cargo.voice?'Para un agente presione 0. ':'')+'Para salir '+(cargo.voice?'presione la tecla de asterisco o ':'')+cargo.verb_es+' SALIR.'")),
|
|
264
264
|
when('retry_unknown_key', '/^\\s*[2-8]\\s*$/.test(user_choice)', call('retry_bad_key_collect', 'collect-service-answer', { profiles: '{{retry_profiles}}', question: '{{retry_question}}', question_es: '{{retry_question_es}}', keypad: { min: 1, max: 1 }, parent_form: '{{parent_form}}' })),
|
|
265
|
-
set('retry_latest_answer', 'user_choice', 'String(cargo.serviceAnswer.raw || "")'), set('retry_capture', 'smart_capture_result', 'capture_patterns && capture_patterns.length ? normalizeAndFindCapture(user_choice,capture_patterns) : null'),
|
|
265
|
+
set('retry_latest_answer', 'user_choice', 'String(cargo.serviceAnswer.raw || "").trim().replace(/[.,!?;:]+$/,"")'), set('retry_capture', 'smart_capture_result', 'capture_patterns && capture_patterns.length ? normalizeAndFindCapture(user_choice,capture_patterns) : null'),
|
|
266
266
|
cases('retry_capture_route', { 'condition: smart_capture_result && retry_call_type === "replace"': call('retry_captured_replace', '{{retry_flow}}', { cell_number: '', email: '', '{{smart_capture_result.variable}}': '{{smart_capture_result.value}}', retry_flow: '{{retry_flow}}', cancel_flow: '{{cancel_flow}}', retrying: true, contact_options: null, parent_form: '{{parent_form}}' }, 'replace'), 'condition: smart_capture_result': call('retry_captured_reboot', '{{retry_flow}}', { '{{smart_capture_result.variable}}': '{{smart_capture_result.value}}', retry_flow: '{{retry_flow}}', cancel_flow: '{{cancel_flow}}', retrying: true, contact_options: null, parent_form: '{{parent_form}}' }, 'reboot'), default: effect('retry_no_capture', 'true') }),
|
|
267
267
|
set('retry_typed_code', 'normalized_otp_code', "allow_code_entry && user_choice.replace(/\\D/g,'').length === 6 ? user_choice.replace(/\\D/g,'') : ''"), when('retry_validate_code', '!!normalized_otp_code', call('retry_code_validate', 'validate-otp-code')),
|
|
268
268
|
cases('retry_decision', { 'condition: normalized_otp_code && cargo.otpVerified === true': end('retry_verified'), "condition: (user_choice.trim() === '1' || isAnswer(user_choice,'yes',retry_yes_words)) && retry_call_type === 'replace'": call('retry_yes_replace', '{{retry_flow}}', { retrying: true, cell_number: '', email: '', contact_options: null, parent_form: '{{parent_form}}' }, 'replace'), "condition: user_choice.trim() === '1' || isAnswer(user_choice,'yes',retry_yes_words)": call('retry_yes_reboot', '{{retry_flow}}', { retrying: true, contact_options: null, parent_form: '{{parent_form}}' }, 'reboot'), "condition: user_choice.trim() === '9' || isAnswer(user_choice,'text')": call('retry_text', 'switch-to-text', undefined, 'reboot'), "condition: isAgentRequest(user_choice)": call('retry_agent', 'live-agent-requested', undefined, 'reboot'), "condition: !user_choice.trim() || /^\\d$/.test(user_choice.trim()) || isExitRequest(user_choice)": call('retry_cancel', '{{cancel_flow}}', undefined, 'reboot'), default: { id: 'retry_dispatch', type: 'DISPATCH', outcome: '{{caller_outcome}}', reason: '{{caller_reason}}' } })
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contact.d.ts","sourceRoot":"","sources":["../../src/helpers/contact.js"],"names":[],"mappings":"AAiBA;;;;;;;;GAQG;AACH;;
|
|
1
|
+
{"version":3,"file":"contact.d.ts","sourceRoot":"","sources":["../../src/helpers/contact.js"],"names":[],"mappings":"AAiBA;;;;;;;;GAQG;AACH;;WAiCC;AAID;;;;;GAKG;AACH,0CAWC;AAED;;;;;GAKG;AACH,0DAgBC;AAED,qHAAqH;AACrH,2DAIC;AAED;;;;GAIG;AACH;;;SAmBC;AAED;;;GAGG;AACH,sDAOC;AAED;;;;;GAKG;AACH,yEAUC;AAQD;;;;;GAKG;AACH,qDAIC;AAED,mHAAmH;AACnH,oDAIC"}
|
package/dist/helpers/contact.js
CHANGED
|
@@ -40,7 +40,10 @@ export function readEmail(text, { literal = false } = {}) {
|
|
|
40
40
|
return '';
|
|
41
41
|
}
|
|
42
42
|
else {
|
|
43
|
-
|
|
43
|
+
// a spelled domain arrives in pieces ("gm a i l.com", "y a h o o . c o m"): join them up to its top-level domain
|
|
44
|
+
const after = spoken.slice(at + 1).trim();
|
|
45
|
+
const spelled = after.match(/^[a-z0-9-]+(?:\s+[a-z0-9-]+){1,12}?(?:\s*\.\s*(?:[a-z]{2,}|[a-z](?:\s+[a-z]){1,2})\b){1,2}/i);
|
|
46
|
+
const domain = (spelled ? spelled[0].replace(/\s+/g, '') : (after.match(/^[^\s@]+/) || [''])[0]).replace(/[.,;:!?]+$/, '');
|
|
44
47
|
const pieces = spoken.slice(0, at).replace(/@/g, ' ').normalize('NFD').replace(/[\u0300-\u036f]/g, '').split(/[\s,;:!?]+/).map((w) => w.replace(/^[^a-z0-9]+|[^a-z0-9]+$/gi, '')).filter(Boolean);
|
|
45
48
|
const local = [];
|
|
46
49
|
for (let k = pieces.length - 1; k >= 0 && local.join('').length < 64; k--) {
|
|
@@ -61,7 +61,9 @@ export declare function decodeReplyRankLlm(text: string, request: ReplyRankReque
|
|
|
61
61
|
};
|
|
62
62
|
/**
|
|
63
63
|
* System One's answers as the canonical reply: the highest-rated option when it clears the cut, else the default
|
|
64
|
-
* (`answers`), with every option's probability (for logs).
|
|
64
|
+
* (`answers`), with every option's probability (for logs). A declared choice that clears the cut is taken over `answers`
|
|
65
|
+
* ("picks none of them") and `new_request`; only `abort` keeps its rank (owner 2026-10-28: a reply rated its menu
|
|
66
|
+
* choice 0.65 and `answers` 0.81, and the menu was asked again). Throws if any question is unanswered.
|
|
65
67
|
*/
|
|
66
68
|
export declare function decodeReplyRankSystemOne(answers: Record<string, {
|
|
67
69
|
noul?: unknown;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reply-rank.d.ts","sourceRoot":"","sources":["../../src/host/reply-rank.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,eAAO,MAAM,aAAa,8CAA+C,CAAC;AAC1E,kEAAkE;AAClE,MAAM,MAAM,WAAW,GAAG,OAAO,aAAa,CAAC,MAAM,CAAC,GAAG,UAAU,MAAM,EAAE,CAAC;AAC5E,0FAA0F;AAC1F,MAAM,WAAW,WAAW;IAAG,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE;AAC3D,eAAO,MAAM,aAAa,YAAY,CAAC;AACvC,gGAAgG;AAChG,eAAO,MAAM,aAAa,EAAE,WAAuB,CAAC;AACpD,wCAAwC;AACxC,eAAO,MAAM,mBAAmB,MAAM,CAAC;AAEvC,MAAM,WAAW,SAAS;IAAG,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE;AAC1E,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,YAAY,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,SAAS,EAAE,CAAC;IAC1B,yFAAyF;IACzF,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,0DAA0D;IAC1D,OAAO,CAAC,EAAE,WAAW,EAAE,CAAC;IACxB,GAAG,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC;IACvE,SAAS,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAAC,KAAK,EAAE;YAAE,EAAE,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,WAAW,CAAA;SAAE,EAAE,CAAA;KAAE,CAAC;CACjI;AAwCD,0DAA0D;AAC1D,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,SAAS,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAE,WAAW,EAAO,GAAG,gBAAgB,CA0CxI;AAED,4FAA4F;AAC5F,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,GAAG;IAAE,MAAM,EAAE,WAAW,CAAA;CAAE,CAMnG;AAED
|
|
1
|
+
{"version":3,"file":"reply-rank.d.ts","sourceRoot":"","sources":["../../src/host/reply-rank.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,eAAO,MAAM,aAAa,8CAA+C,CAAC;AAC1E,kEAAkE;AAClE,MAAM,MAAM,WAAW,GAAG,OAAO,aAAa,CAAC,MAAM,CAAC,GAAG,UAAU,MAAM,EAAE,CAAC;AAC5E,0FAA0F;AAC1F,MAAM,WAAW,WAAW;IAAG,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE;AAC3D,eAAO,MAAM,aAAa,YAAY,CAAC;AACvC,gGAAgG;AAChG,eAAO,MAAM,aAAa,EAAE,WAAuB,CAAC;AACpD,wCAAwC;AACxC,eAAO,MAAM,mBAAmB,MAAM,CAAC;AAEvC,MAAM,WAAW,SAAS;IAAG,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE;AAC1E,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,YAAY,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,SAAS,EAAE,CAAC;IAC1B,yFAAyF;IACzF,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,0DAA0D;IAC1D,OAAO,CAAC,EAAE,WAAW,EAAE,CAAC;IACxB,GAAG,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC;IACvE,SAAS,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAAC,KAAK,EAAE;YAAE,EAAE,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,WAAW,CAAA;SAAE,EAAE,CAAA;KAAE,CAAC;CACjI;AAwCD,0DAA0D;AAC1D,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,SAAS,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAE,WAAW,EAAO,GAAG,gBAAgB,CA0CxI;AAED,4FAA4F;AAC5F,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,GAAG;IAAE,MAAM,EAAE,WAAW,CAAA;CAAE,CAMnG;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE;IAAE,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,SAAS,CAAC,GAAG,SAAS,EACnE,OAAO,EAAE,gBAAgB,EACzB,EAAE,SAA+B,EAAE;;CAAK,GACvC;IAAE,MAAM,EAAE,WAAW,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,CAe5E;AAED,+FAA+F;AAC/F,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,IAAI,gBAAgB,CAGhF"}
|
package/dist/host/reply-rank.js
CHANGED
|
@@ -111,7 +111,9 @@ export function decodeReplyRankLlm(text, request) {
|
|
|
111
111
|
}
|
|
112
112
|
/**
|
|
113
113
|
* System One's answers as the canonical reply: the highest-rated option when it clears the cut, else the default
|
|
114
|
-
* (`answers`), with every option's probability (for logs).
|
|
114
|
+
* (`answers`), with every option's probability (for logs). A declared choice that clears the cut is taken over `answers`
|
|
115
|
+
* ("picks none of them") and `new_request`; only `abort` keeps its rank (owner 2026-10-28: a reply rated its menu
|
|
116
|
+
* choice 0.65 and `answers` 0.81, and the menu was asked again). Throws if any question is unanswered.
|
|
115
117
|
*/
|
|
116
118
|
export function decodeReplyRankSystemOne(answers, request, { threshold = REPLY_YES_THRESHOLD } = {}) {
|
|
117
119
|
const scores = {};
|
|
@@ -121,7 +123,9 @@ export function decodeReplyRankSystemOne(answers, request, { threshold = REPLY_Y
|
|
|
121
123
|
throw new Error(`System One: question ${q.id} unanswered`);
|
|
122
124
|
scores[q.option] = noul;
|
|
123
125
|
}
|
|
124
|
-
const
|
|
126
|
+
const ranked = request.systemOne.index.map(q => q.option).sort((a, b) => scores[b] - scores[a]);
|
|
127
|
+
const choice = ranked.find(o => o.startsWith(CHOICE_PREFIX) && scores[o] >= threshold);
|
|
128
|
+
const best = choice && ranked[0] !== 'abort' ? choice : ranked[0];
|
|
125
129
|
if (best && scores[best] >= threshold) {
|
|
126
130
|
return { option: best, scores, fallback: false };
|
|
127
131
|
}
|
package/dist/runtime-identity.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const JSFE_RUNTIME_FINGERPRINT = "sha256:
|
|
1
|
+
export const JSFE_RUNTIME_FINGERPRINT = "sha256:9fa908654ad5402560cc1cf51e4cd57d1bff01735b4e31d6fc0bb4f5f519ceb1";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jsfe",
|
|
3
|
-
"version": "1.14.
|
|
3
|
+
"version": "1.14.1",
|
|
4
4
|
"description": "TypeScript workflow engine for conversational/automation apps: multi-flow orchestration, interrupt/resume, stack-based control, robust errors, and flexible tool/REST integration.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Ron Pinkas",
|