'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); }