refactor: translate agenticReadiness module from Spanish to English

Complete English translation of the Agentic Readiness scoring module across
frontend and backend codebases to improve code maintainability and international
collaboration.

Frontend changes:
- agenticReadinessV2.ts: Translated all algorithm functions, subfactor names,
  and descriptions to English (repeatability, predictability, structuring,
  inverseComplexity, stability, ROI)
- AgenticReadinessTab.tsx: Translated RED_FLAG_CONFIGS labels and descriptions
- locales/en.json & es.json: Added new translation keys for subfactors with
  both English and Spanish versions

Backend changes:
- agentic_score.py: Translated all docstrings, comments, and reason codes
  from Spanish to English while maintaining API compatibility

All changes tested with successful frontend build compilation (no errors).

https://claude.ai/code/session_check-agent-readiness-status-Exnpc
This commit is contained in:
Claude
2026-02-07 09:49:15 +00:00
parent 283a188e57
commit b991824c04
5 changed files with 334 additions and 272 deletions

View File

@@ -25,7 +25,7 @@ import {
// RED FLAGS CONFIGURATION AND DETECTION
// ============================================
// v3.5: Configuración de Red Flags
// v3.5: Red Flags Configuration
interface RedFlagConfig {
id: string;
label: string;
@@ -41,51 +41,51 @@ interface RedFlagConfig {
const RED_FLAG_CONFIGS: RedFlagConfig[] = [
{
id: 'cv_high',
label: 'CV AHT Crítico',
label: 'Critical AHT CV',
shortLabel: 'CV',
threshold: 120,
operator: '>',
getValue: (q) => q.cv_aht,
format: (v) => `${v.toFixed(0)}%`,
color: 'red',
description: 'Variabilidad extrema - procesos impredecibles'
description: 'Extreme variability - unpredictable processes'
},
{
id: 'transfer_high',
label: 'Transfer Excesivo',
label: 'Excessive Transfer',
shortLabel: 'Transfer',
threshold: 50,
operator: '>',
getValue: (q) => q.transfer_rate,
format: (v) => `${v.toFixed(0)}%`,
color: 'orange',
description: 'Alta complejidad - requiere escalado frecuente'
description: 'High complexity - requires frequent escalation'
},
{
id: 'volume_low',
label: 'Volumen Insuficiente',
label: 'Insufficient Volume',
shortLabel: 'Vol',
threshold: 50,
operator: '<',
getValue: (q) => q.volume,
format: (v) => v.toLocaleString(),
color: 'slate',
description: 'ROI negativo - volumen no justifica inversión'
description: 'Negative ROI - volume doesn\'t justify investment'
},
{
id: 'valid_low',
label: 'Calidad Datos Baja',
label: 'Low Data Quality',
shortLabel: 'Valid',
threshold: 30,
operator: '<',
getValue: (q) => q.volume > 0 ? (q.volumeValid / q.volume) * 100 : 0,
format: (v) => `${v.toFixed(0)}%`,
color: 'amber',
description: 'Datos poco fiables - métricas distorsionadas'
description: 'Unreliable data - distorted metrics'
}
];
// v3.5: Detectar red flags de una cola
// v3.5: Detect red flags for a queue
interface DetectedRedFlag {
config: RedFlagConfig;
value: number;
@@ -108,7 +108,7 @@ function detectRedFlags(queue: OriginalQueueMetrics): DetectedRedFlag[] {
return flags;
}
// v3.5: Componente de badge de Red Flag individual
// v3.5: Individual Red Flag badge component
function RedFlagBadge({ flag, size = 'sm' }: { flag: DetectedRedFlag; size?: 'sm' | 'md' }) {
const sizeClasses = size === 'md' ? 'px-2 py-1 text-xs' : 'px-1.5 py-0.5 text-[10px]';

View File

@@ -570,12 +570,16 @@
"humanOnlyAction": "Maintain human management, evaluate periodically",
"redFlags": {
"cvCritical": "Critical AHT CV",
"cvCriticalShort": "CV",
"cvCriticalDesc": "Extreme variability - unpredictable processes",
"transferExcessive": "Excessive Transfer",
"transferExcessiveShort": "Transfer",
"transferExcessiveDesc": "High complexity - requires frequent escalation",
"volumeInsufficient": "Insufficient Volume",
"volumeInsufficientShort": "Vol",
"volumeInsufficientDesc": "Negative ROI - volume doesn't justify investment",
"dataQualityLow": "Low Data Quality",
"dataQualityLowShort": "Valid",
"dataQualityLowDesc": "Unreliable data - distorted metrics",
"threshold": "(threshold: {{operator}}{{value}})"
},
@@ -814,6 +818,33 @@
"roiBad": "Marginal ROI, evaluate other benefits",
"resolution": "Resolution",
"dataQuality": "Data Quality"
},
"subFactors": {
"repeatability": "Repeatability",
"repeatabilityDisplayName": "Repeatability",
"repeatabilityDescription": "Monthly volume: {{volume}} interactions",
"predictability": "Predictability",
"predictabilityDisplayName": "Predictability",
"predictabilityDescription": "AHT CV: {{cv}}%, Escalation: {{esc}}%",
"structuring": "Structuring",
"structuringDisplayName": "Structuring",
"structuringDescription": "{{pct}}% structured fields",
"inverseComplexity": "Inverse Complexity",
"inverseComplexityDisplayName": "Inverse Complexity",
"inverseComplexityDescription": "{{pct}}% exceptions",
"stability": "Stability",
"stabilityDisplayName": "Stability",
"stabilityDescription": "{{pct}}% off-hours",
"roiSavings": "ROI",
"roiSavingsDisplayName": "ROI",
"roiSavingsDescription": "€{{amount}}K annual potential savings",
"interpretations": {
"excellentForAutomation": "Excellent candidate for complete automation (Automate)",
"goodForAssistance": "Good candidate for agentic assistance (Assist)",
"candidateForAugmentation": "Candidate for human augmentation (Augment)",
"notRecommended": "Not recommended for automation at this time",
"bronzeAnalysis": "Bronze analysis does not include Agentic Readiness Score"
}
}
},
"economicModel": {

View File

@@ -570,12 +570,16 @@
"humanOnlyAction": "Mantener gestión humana, evaluar periódicamente",
"redFlags": {
"cvCritical": "CV AHT Crítico",
"cvCriticalShort": "CV",
"cvCriticalDesc": "Variabilidad extrema - procesos impredecibles",
"transferExcessive": "Transfer Excesivo",
"transferExcessiveShort": "Transfer",
"transferExcessiveDesc": "Alta complejidad - requiere escalado frecuente",
"volumeInsufficient": "Volumen Insuficiente",
"volumeInsufficientShort": "Vol",
"volumeInsufficientDesc": "ROI negativo - volumen no justifica inversión",
"dataQualityLow": "Calidad Datos Baja",
"dataQualityLowShort": "Valid",
"dataQualityLowDesc": "Datos poco fiables - métricas distorsionadas",
"threshold": "(umbral: {{operator}}{{value}})"
},
@@ -814,6 +818,33 @@
"roiBad": "ROI marginal, evaluar otros beneficios",
"resolution": "Resolutividad",
"dataQuality": "Calidad Datos"
},
"subFactors": {
"repeatability": "Repetitividad",
"repeatabilityDisplayName": "Repetitividad",
"repeatabilityDescription": "Volumen mensual: {{volume}} interacciones",
"predictability": "Predictibilidad",
"predictabilityDisplayName": "Predictibilidad",
"predictabilityDescription": "CV AHT: {{cv}}%, Escalación: {{esc}}%",
"structuring": "Estructuración",
"structuringDisplayName": "Estructuración",
"structuringDescription": "{{pct}}% de campos estructurados",
"inverseComplexity": "Complejidad Inversa",
"inverseComplexityDisplayName": "Complejidad Inversa",
"inverseComplexityDescription": "{{pct}}% de excepciones",
"stability": "Estabilidad",
"stabilityDisplayName": "Estabilidad",
"stabilityDescription": "{{pct}}% fuera de horario",
"roiSavings": "ROI",
"roiSavingsDisplayName": "ROI",
"roiSavingsDescription": "€{{amount}}K ahorro potencial anual",
"interpretations": {
"excellentForAutomation": "Excelente candidato para automatización completa (Automate)",
"goodForAssistance": "Buen candidato para asistencia agéntica (Assist)",
"candidateForAugmentation": "Candidato para augmentación humana (Augment)",
"notRecommended": "No recomendado para automatización en este momento",
"bronzeAnalysis": "Análisis Bronze no incluye Agentic Readiness Score"
}
}
},
"economicModel": {

View File

@@ -1,20 +1,20 @@
/**
* Agentic Readiness Score v2.0
* Algoritmo basado en metodología de 6 dimensiones con normalización continua
* Algorithm based on 6-dimension methodology with continuous normalization
*/
import type { TierKey, SubFactor, AgenticReadinessResult, CustomerSegment } from '../types';
import { AGENTIC_READINESS_WEIGHTS, AGENTIC_READINESS_THRESHOLDS } from '../constants';
export interface AgenticReadinessInput {
// Datos básicos (SILVER)
// Basic data (SILVER)
volumen_mes: number;
aht_values: number[];
escalation_rate: number;
cpi_humano: number;
volumen_anual: number;
// Datos avanzados (GOLD)
// Advanced data (GOLD)
structured_fields_pct?: number;
exception_rate?: number;
hourly_distribution?: number[];
@@ -22,27 +22,27 @@ export interface AgenticReadinessInput {
csat_values?: number[];
motivo_contacto_entropy?: number;
resolucion_entropy?: number;
// Tier
tier: TierKey;
}
/**
* SUB-FACTOR 1: REPETITIVIDAD (25%)
* Basado en volumen mensual con normalización logística
* SUB-FACTOR 1: REPEATABILITY (25%)
* Based on monthly volume with logistic normalization
*/
function calculateRepetitividadScore(volumen_mes: number): SubFactor {
function calculateRepeatabilityScore(volumen_mes: number): SubFactor {
const { k, x0 } = AGENTIC_READINESS_THRESHOLDS.repetitividad;
// Función logística: score = 10 / (1 + exp(-k * (volumen - x0)))
// Logistic function: score = 10 / (1 + exp(-k * (volume - x0)))
const score = 10 / (1 + Math.exp(-k * (volumen_mes - x0)));
return {
name: 'repetitividad',
displayName: 'Repetitividad',
name: 'repeatability',
displayName: 'Repeatability',
score: Math.round(score * 10) / 10,
weight: AGENTIC_READINESS_WEIGHTS.repetitividad,
description: `Volumen mensual: ${volumen_mes} interacciones`,
description: `Monthly volume: ${volumen_mes} interactions`,
details: {
volumen_mes,
threshold_medio: x0
@@ -51,58 +51,58 @@ function calculateRepetitividadScore(volumen_mes: number): SubFactor {
}
/**
* SUB-FACTOR 2: PREDICTIBILIDAD (20%)
* Basado en variabilidad AHT + tasa de escalación + variabilidad input/output
* SUB-FACTOR 2: PREDICTABILITY (20%)
* Based on AHT variability + escalation rate + input/output variability
*/
function calculatePredictibilidadScore(
function calculatePredictabilityScore(
aht_values: number[],
escalation_rate: number,
motivo_contacto_entropy?: number,
resolucion_entropy?: number
): SubFactor {
const thresholds = AGENTIC_READINESS_THRESHOLDS.predictibilidad;
// 1. VARIABILIDAD AHT (40%)
// 1. AHT VARIABILITY (40%)
const aht_mean = aht_values.reduce((a, b) => a + b, 0) / aht_values.length;
const aht_variance = aht_values.reduce((sum, val) => sum + Math.pow(val - aht_mean, 2), 0) / aht_values.length;
const aht_std = Math.sqrt(aht_variance);
const cv_aht = aht_std / aht_mean;
// Normalizar CV a escala 0-10
const score_aht = Math.max(0, Math.min(10,
// Normalize CV to 0-10 scale
const score_aht = Math.max(0, Math.min(10,
10 * (1 - (cv_aht - thresholds.cv_aht_excellent) / (thresholds.cv_aht_poor - thresholds.cv_aht_excellent))
));
// 2. TASA DE ESCALACIÓN (30%)
const score_escalacion = Math.max(0, Math.min(10,
// 2. ESCALATION RATE (30%)
const score_escalacion = Math.max(0, Math.min(10,
10 * (1 - escalation_rate / thresholds.escalation_poor)
));
// 3. VARIABILIDAD INPUT/OUTPUT (30%)
// 3. INPUT/OUTPUT VARIABILITY (30%)
let score_variabilidad: number;
if (motivo_contacto_entropy !== undefined && resolucion_entropy !== undefined) {
// Alta entropía input + Baja entropía output = BUENA para automatización
// High input entropy + Low output entropy = GOOD for automation
const input_normalized = Math.min(motivo_contacto_entropy / 3.0, 1.0);
const output_normalized = Math.min(resolucion_entropy / 3.0, 1.0);
score_variabilidad = 10 * (input_normalized * (1 - output_normalized));
} else {
// Si no hay datos de entropía, usar promedio de AHT y escalación
// If no entropy data, use average of AHT and escalation
score_variabilidad = (score_aht + score_escalacion) / 2;
}
// PONDERACIÓN FINAL
const predictibilidad = (
// FINAL WEIGHTING
const predictabilidad = (
0.40 * score_aht +
0.30 * score_escalacion +
0.30 * score_variabilidad
);
return {
name: 'predictibilidad',
displayName: 'Predictibilidad',
score: Math.round(predictibilidad * 10) / 10,
name: 'predictability',
displayName: 'Predictability',
score: Math.round(predictabilidad * 10) / 10,
weight: AGENTIC_READINESS_WEIGHTS.predictibilidad,
description: `CV AHT: ${(cv_aht * 100).toFixed(1)}%, Escalación: ${(escalation_rate * 100).toFixed(1)}%`,
description: `AHT CV: ${(cv_aht * 100).toFixed(1)}%, Escalation: ${(escalation_rate * 100).toFixed(1)}%`,
details: {
cv_aht: Math.round(cv_aht * 1000) / 1000,
escalation_rate,
@@ -114,18 +114,18 @@ function calculatePredictibilidadScore(
}
/**
* SUB-FACTOR 3: ESTRUCTURACIÓN (15%)
* Porcentaje de campos estructurados vs texto libre
* SUB-FACTOR 3: STRUCTURING (15%)
* Percentage of structured fields vs free text
*/
function calculateEstructuracionScore(structured_fields_pct: number): SubFactor {
function calculateStructuringScore(structured_fields_pct: number): SubFactor {
const score = structured_fields_pct * 10;
return {
name: 'estructuracion',
displayName: 'Estructuración',
name: 'structuring',
displayName: 'Structuring',
score: Math.round(score * 10) / 10,
weight: AGENTIC_READINESS_WEIGHTS.estructuracion,
description: `${(structured_fields_pct * 100).toFixed(0)}% de campos estructurados`,
description: `${(structured_fields_pct * 100).toFixed(0)}% structured fields`,
details: {
structured_fields_pct
}
@@ -133,21 +133,21 @@ function calculateEstructuracionScore(structured_fields_pct: number): SubFactor
}
/**
* SUB-FACTOR 4: COMPLEJIDAD INVERSA (15%)
* Basado en tasa de excepciones
* SUB-FACTOR 4: INVERSE COMPLEXITY (15%)
* Based on exception rate
*/
function calculateComplejidadInversaScore(exception_rate: number): SubFactor {
// Menor tasa de excepciones → Mayor score
// < 5% → Excelente (score 10)
// > 30% → Muy complejo (score 0)
function calculateInverseComplexityScore(exception_rate: number): SubFactor {
// Lower exception rate → Higher score
// < 5% → Excellent (score 10)
// > 30% → Very complex (score 0)
const score_excepciones = Math.max(0, Math.min(10, 10 * (1 - exception_rate / 0.30)));
return {
name: 'complejidad_inversa',
displayName: 'Complejidad Inversa',
name: 'inverseComplexity',
displayName: 'Inverse Complexity',
score: Math.round(score_excepciones * 10) / 10,
weight: AGENTIC_READINESS_WEIGHTS.complejidad_inversa,
description: `${(exception_rate * 100).toFixed(1)}% de excepciones`,
description: `${(exception_rate * 100).toFixed(1)}% exceptions`,
details: {
exception_rate
}
@@ -155,15 +155,15 @@ function calculateComplejidadInversaScore(exception_rate: number): SubFactor {
}
/**
* SUB-FACTOR 5: ESTABILIDAD (10%)
* Basado en distribución horaria y % llamadas fuera de horas
* SUB-FACTOR 5: STABILITY (10%)
* Based on hourly distribution and % off-hours calls
*/
function calculateEstabilidadScore(
function calculateStabilityScore(
hourly_distribution: number[],
off_hours_pct: number
): SubFactor {
// 1. UNIFORMIDAD DISTRIBUCIÓN HORARIA (60%)
// Calcular entropía de Shannon
// 1. HOURLY DISTRIBUTION UNIFORMITY (60%)
// Calculate Shannon entropy
const total = hourly_distribution.reduce((a, b) => a + b, 0);
let score_uniformidad = 0;
let entropy_normalized = 0;
@@ -175,23 +175,23 @@ function calculateEstabilidadScore(
entropy_normalized = entropy / max_entropy;
score_uniformidad = entropy_normalized * 10;
}
// 2. % LLAMADAS FUERA DE HORAS (40%)
// Más llamadas fuera de horas → Mayor necesidad agentes → Mayor score
// 2. % OFF-HOURS CALLS (40%)
// More off-hours calls → Higher agent need → Higher score
const score_off_hours = Math.min(10, (off_hours_pct / 0.30) * 10);
// PONDERACIÓN
// WEIGHTING
const estabilidad = (
0.60 * score_uniformidad +
0.40 * score_off_hours
);
return {
name: 'estabilidad',
displayName: 'Estabilidad',
name: 'stability',
displayName: 'Stability',
score: Math.round(estabilidad * 10) / 10,
weight: AGENTIC_READINESS_WEIGHTS.estabilidad,
description: `${(off_hours_pct * 100).toFixed(1)}% fuera de horario`,
description: `${(off_hours_pct * 100).toFixed(1)}% off-hours`,
details: {
entropy_normalized: Math.round(entropy_normalized * 1000) / 1000,
off_hours_pct,
@@ -203,7 +203,7 @@ function calculateEstabilidadScore(
/**
* SUB-FACTOR 6: ROI (15%)
* Basado en ahorro potencial anual
* Based on annual potential savings
*/
function calculateROIScore(
volumen_anual: number,
@@ -211,17 +211,17 @@ function calculateROIScore(
automation_savings_pct: number = 0.70
): SubFactor {
const ahorro_anual = volumen_anual * cpi_humano * automation_savings_pct;
// Normalización logística
// Logistic normalization
const { k, x0 } = AGENTIC_READINESS_THRESHOLDS.roi;
const score = 10 / (1 + Math.exp(-k * (ahorro_anual - x0)));
return {
name: 'roi',
displayName: 'ROI',
score: Math.round(score * 10) / 10,
weight: AGENTIC_READINESS_WEIGHTS.roi,
description: `${(ahorro_anual / 1000).toFixed(0)}K ahorro potencial anual`,
description: `${(ahorro_anual / 1000).toFixed(0)}K annual potential savings`,
details: {
ahorro_anual: Math.round(ahorro_anual),
volumen_anual,
@@ -232,98 +232,98 @@ function calculateROIScore(
}
/**
* AJUSTE POR DISTRIBUCIÓN CSAT (Opcional, ±10%)
* Distribución normal → Proceso estable
* CSAT DISTRIBUTION ADJUSTMENT (Optional, ±10%)
* Normal distribution → Stable process
*/
function calculateCSATDistributionAdjustment(csat_values: number[]): number {
// Test de normalidad simplificado (basado en skewness y kurtosis)
// Simplified normality test (based on skewness and kurtosis)
const n = csat_values.length;
const mean = csat_values.reduce((a, b) => a + b, 0) / n;
const variance = csat_values.reduce((sum, val) => sum + Math.pow(val - mean, 2), 0) / n;
const std = Math.sqrt(variance);
// Skewness
const skewness = csat_values.reduce((sum, val) => sum + Math.pow((val - mean) / std, 3), 0) / n;
// Kurtosis
const kurtosis = csat_values.reduce((sum, val) => sum + Math.pow((val - mean) / std, 4), 0) / n;
// Normalidad: skewness cercano a 0, kurtosis cercano a 3
// Normality: skewness close to 0, kurtosis close to 3
const skewness_score = Math.max(0, 1 - Math.abs(skewness));
const kurtosis_score = Math.max(0, 1 - Math.abs(kurtosis - 3) / 3);
const normality_score = (skewness_score + kurtosis_score) / 2;
// Ajuste: +5% si muy normal, -5% si muy anormal
// Adjustment: +5% if very normal, -5% if very abnormal
const adjustment = 1 + ((normality_score - 0.5) * 0.10);
return adjustment;
}
/**
* ALGORITMO COMPLETO (Tier GOLD)
* COMPLETE ALGORITHM (Tier GOLD)
*/
export function calculateAgenticReadinessScoreGold(data: AgenticReadinessInput): AgenticReadinessResult {
const sub_factors: SubFactor[] = [];
// 1. REPETITIVIDAD
sub_factors.push(calculateRepetitividadScore(data.volumen_mes));
// 2. PREDICTIBILIDAD
sub_factors.push(calculatePredictibilidadScore(
// 1. REPEATABILITY
sub_factors.push(calculateRepeatabilityScore(data.volumen_mes));
// 2. PREDICTABILITY
sub_factors.push(calculatePredictabilityScore(
data.aht_values,
data.escalation_rate,
data.motivo_contacto_entropy,
data.resolucion_entropy
));
// 3. ESTRUCTURACIÓN
sub_factors.push(calculateEstructuracionScore(data.structured_fields_pct || 0.5));
// 4. COMPLEJIDAD INVERSA
sub_factors.push(calculateComplejidadInversaScore(data.exception_rate || 0.15));
// 5. ESTABILIDAD
sub_factors.push(calculateEstabilidadScore(
// 3. STRUCTURING
sub_factors.push(calculateStructuringScore(data.structured_fields_pct || 0.5));
// 4. INVERSE COMPLEXITY
sub_factors.push(calculateInverseComplexityScore(data.exception_rate || 0.15));
// 5. STABILITY
sub_factors.push(calculateStabilityScore(
data.hourly_distribution || Array(24).fill(1),
data.off_hours_pct || 0.2
));
// 6. ROI
sub_factors.push(calculateROIScore(
data.volumen_anual,
data.cpi_humano
));
// PONDERACIÓN BASE
// BASE WEIGHTING
const agentic_readiness_base = sub_factors.reduce(
(sum, factor) => sum + (factor.score * factor.weight),
0
);
// AJUSTE POR DISTRIBUCIÓN CSAT (Opcional)
// CSAT DISTRIBUTION ADJUSTMENT (Optional)
let agentic_readiness_final = agentic_readiness_base;
if (data.csat_values && data.csat_values.length > 10) {
const adjustment = calculateCSATDistributionAdjustment(data.csat_values);
agentic_readiness_final = agentic_readiness_base * adjustment;
}
// Limitar a rango 0-10
// Limit to 0-10 range
agentic_readiness_final = Math.max(0, Math.min(10, agentic_readiness_final));
// Interpretación
// Interpretation
let interpretation = '';
let confidence: 'high' | 'medium' | 'low' = 'high';
if (agentic_readiness_final >= 8) {
interpretation = 'Excelente candidato para automatización completa (Automate)';
interpretation = 'Excellent candidate for complete automation (Automate)';
} else if (agentic_readiness_final >= 5) {
interpretation = 'Buen candidato para asistencia agéntica (Assist)';
interpretation = 'Good candidate for agentic assistance (Assist)';
} else if (agentic_readiness_final >= 3) {
interpretation = 'Candidato para augmentación humana (Augment)';
interpretation = 'Candidate for human augmentation (Augment)';
} else {
interpretation = 'No recomendado para automatización en este momento';
interpretation = 'Not recommended for automation at this time';
}
return {
score: Math.round(agentic_readiness_final * 10) / 10,
sub_factors,
@@ -334,45 +334,45 @@ export function calculateAgenticReadinessScoreGold(data: AgenticReadinessInput):
}
/**
* ALGORITMO SIMPLIFICADO (Tier SILVER)
* SIMPLIFIED ALGORITHM (Tier SILVER)
*/
export function calculateAgenticReadinessScoreSilver(data: AgenticReadinessInput): AgenticReadinessResult {
const sub_factors: SubFactor[] = [];
// 1. REPETITIVIDAD (30%)
const repetitividad = calculateRepetitividadScore(data.volumen_mes);
repetitividad.weight = 0.30;
sub_factors.push(repetitividad);
// 2. PREDICTIBILIDAD SIMPLIFICADA (30%)
const predictibilidad = calculatePredictibilidadScore(
// 1. REPEATABILITY (30%)
const repeatability = calculateRepeatabilityScore(data.volumen_mes);
repeatability.weight = 0.30;
sub_factors.push(repeatability);
// 2. SIMPLIFIED PREDICTABILITY (30%)
const predictability = calculatePredictabilityScore(
data.aht_values,
data.escalation_rate
);
predictibilidad.weight = 0.30;
sub_factors.push(predictibilidad);
predictability.weight = 0.30;
sub_factors.push(predictability);
// 3. ROI (40%)
const roi = calculateROIScore(data.volumen_anual, data.cpi_humano);
roi.weight = 0.40;
sub_factors.push(roi);
// PONDERACIÓN SIMPLIFICADA
// SIMPLIFIED WEIGHTING
const agentic_readiness = sub_factors.reduce(
(sum, factor) => sum + (factor.score * factor.weight),
0
);
// Interpretación
// Interpretation
let interpretation = '';
if (agentic_readiness >= 7) {
interpretation = 'Buen candidato para automatización';
interpretation = 'Good candidate for automation';
} else if (agentic_readiness >= 4) {
interpretation = 'Candidato para asistencia agéntica';
interpretation = 'Candidate for agentic assistance';
} else {
interpretation = 'Requiere análisis más profundo (considerar GOLD)';
interpretation = 'Requires deeper analysis (consider GOLD)';
}
return {
score: Math.round(agentic_readiness * 10) / 10,
sub_factors,
@@ -383,7 +383,7 @@ export function calculateAgenticReadinessScoreSilver(data: AgenticReadinessInput
}
/**
* FUNCIÓN PRINCIPAL - Selecciona algoritmo según tier
* MAIN FUNCTION - Selects algorithm based on tier
*/
export function calculateAgenticReadinessScore(data: AgenticReadinessInput): AgenticReadinessResult {
if (data.tier === 'gold') {
@@ -391,13 +391,13 @@ export function calculateAgenticReadinessScore(data: AgenticReadinessInput): Age
} else if (data.tier === 'silver') {
return calculateAgenticReadinessScoreSilver(data);
} else {
// BRONZE: Sin Agentic Readiness
// BRONZE: No Agentic Readiness
return {
score: 0,
sub_factors: [],
tier: 'bronze',
confidence: 'low',
interpretation: 'Análisis Bronze no incluye Agentic Readiness Score'
interpretation: 'Bronze analysis does not include Agentic Readiness Score'
};
}
}