| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146 |
- 'use strict';
- const assert = require('assert/strict');
- const {
- SALES_MOVES,
- AgentSalesMovePlanner,
- planSalesMove,
- } = require('../mcp/src/core/agent-sales-move-planner');
- function assertSinglePrimary(plan) {
- assert(SALES_MOVES.includes(plan.primaryMove), plan.primaryMove);
- assert.equal(plan.candidateMoves.filter(candidate => candidate.selected).length, 1);
- assert.equal(plan.candidateMoves.find(candidate => candidate.selected).move, plan.primaryMove);
- }
- function main() {
- assert.deepEqual(SALES_MOVES, [
- 'answer', 'acknowledge_objection', 'clarify', 'recommend', 'advance', 'handoff',
- ]);
- const scenarioPlans = [
- planSalesMove({ scenario: 'direct_question' }),
- planSalesMove({ scenario: 'objection' }),
- planSalesMove({ scenario: 'recommendation_ready' }),
- planSalesMove({ scenario: 'unknown', missingFields: ['goal'] }),
- planSalesMove({ scenario: 'continuation', knownFields: { goal: 'retention' } }),
- ];
- scenarioPlans.forEach(assertSinglePrimary);
- const knownField = planSalesMove({
- scenario: 'first_consultation',
- knownFields: { budget: 20 },
- missingFields: ['budget'],
- guidelines: [{
- id: 'collect-budget',
- condition: { scenario: 'first_consultation', missingFields: ['budget'] },
- action: 'clarify',
- stage: '*',
- priority: 100,
- criticality: 'high',
- track: true,
- }],
- });
- assert.equal(knownField.primaryMove, 'advance');
- assert.deepEqual(knownField.appliedGuidelines, []);
- const objection = planSalesMove({ scenario: 'objection', knownFields: ['goal'] });
- assert.equal(objection.primaryMove, 'acknowledge_objection');
- assert.equal(objection.reason.code, 'scenario_objection');
- const highRisk = planSalesMove({
- scenario: 'recommendation_ready',
- riskLevel: 'high',
- guidelines: [{
- id: 'recommend-now', condition: 'always', action: 'recommend', stage: '*',
- priority: 999, criticality: 'critical', track: true,
- }],
- });
- assert.equal(highRisk.primaryMove, 'handoff');
- assert.equal(highRisk.reason.code, 'high_risk_handoff');
- assert.equal(highRisk.appliedGuidelines[0].id, 'recommend-now');
- const stableTie = planSalesMove({
- scenario: 'continuation',
- guidelines: [
- { id: 'first', condition: 'always', action: 'recommend', priority: 10, criticality: 'normal', track: true },
- { id: 'second', condition: 'always', action: 'advance', priority: 10, criticality: 'normal', track: true },
- ],
- });
- assert.equal(stableTie.primaryMove, 'recommend');
- assert.deepEqual(stableTie.appliedGuidelines.map(item => item.id), ['first', 'second']);
- const completed = planSalesMove({
- scenario: 'continuation',
- completedActions: ['collect-goal'],
- missingFields: ['goal'],
- guidelines: [
- { id: 'collect-goal', condition: 'missing:goal', action: 'clarify', priority: 20, criticality: 'high', track: true },
- { id: 'offer-next-step', condition: 'always', action: 'advance', priority: 10, criticality: 'normal', track: true },
- ],
- });
- assert.equal(completed.primaryMove, 'advance');
- assert.deepEqual(completed.appliedGuidelines.map(item => item.id), ['offer-next-step']);
- const explicit = new AgentSalesMovePlanner({
- guidelines: [{
- id: 'stage-follow-up',
- condition: { scenario: 'continuation', knownFields: ['goal'], notCompletedActions: ['stage-follow-up'] },
- action: 'advance',
- stage: 'follow_up',
- priority: 30,
- criticality: 'medium',
- track: true,
- }],
- }).plan({ scenario: 'continuation', stage: 'follow_up', knownFields: ['goal'] });
- assert.equal(explicit.primaryMove, 'advance');
- assert.equal(explicit.reason.guidelineId, 'stage-follow-up');
- assert.deepEqual(explicit.appliedGuidelines[0].matchChecks.map(check => check.passed), [true, true, true]);
- const safeFallback = planSalesMove({
- scenario: 'unknown',
- guidelines: [{
- id: 'unknown-natural-language-rule', condition: 'customer seems interested', action: 'recommend',
- priority: 100, criticality: 'high', track: true,
- }],
- });
- assert.equal(safeFallback.primaryMove, 'answer');
- assert.equal(safeFallback.reason.code, 'safe_fallback');
- assert.deepEqual(safeFallback.appliedGuidelines, []);
- const incompleteRuleFallback = planSalesMove({
- scenario: 'unknown',
- guidelines: [
- { id: 'empty-object', condition: {}, action: 'recommend', priority: 100, criticality: 'high', track: true },
- { id: 'empty-array', condition: [], action: 'advance', priority: 90, criticality: 'high', track: true },
- ],
- });
- assert.equal(incompleteRuleFallback.primaryMove, 'answer');
- assert.deepEqual(incompleteRuleFallback.appliedGuidelines, []);
- const stageMismatch = planSalesMove({
- scenario: 'continuation',
- stage: 'stage-b',
- knownFields: ['goal'],
- guidelines: [{
- id: 'stage-a-only', condition: 'always', action: 'recommend', stage: 'stage-a',
- priority: 100, criticality: 'critical', track: true,
- }],
- });
- assert.equal(stageMismatch.primaryMove, 'advance');
- assert.deepEqual(stageMismatch.appliedGuidelines, []);
- const plans = [
- ...scenarioPlans, knownField, objection, highRisk, stableTie, completed, explicit, safeFallback,
- incompleteRuleFallback, stageMismatch,
- ];
- plans.forEach(assertSinglePrimary);
- process.stdout.write(`${JSON.stringify({ status: 'ok', checks: 11, plans: plans.length }, null, 2)}\n`);
- }
- try { main(); }
- catch (error) {
- process.stderr.write(`${error.stack || error.message}\n`);
- process.exit(1);
- }
|