Sales-AI-Core / engine.py
Romanchello-bit's picture
Implement scenario simulation and analytics logic
1cbada8
import json
from graph_module import Graph
from algorithms import bellman_ford_list
class SalesEngine:
def __init__(self, json_file='sales_script.json'):
"""Initialize the SalesEngine by loading the sales script from JSON."""
# Load the sales script
with open(json_file, 'r') as f:
data = json.load(f)
self.nodes_data = data['nodes']
self.edges_data = data['edges']
# Create mapping from string IDs to integer IDs
self.str_to_int = {}
self.int_to_str = {}
self.node_text = {}
for idx, node_name in enumerate(self.nodes_data.keys()):
self.str_to_int[node_name] = idx
self.int_to_str[idx] = node_name
self.node_text[node_name] = self.nodes_data[node_name]
# Build the Graph object
num_nodes = len(self.nodes_data)
self.graph = Graph(num_nodes, directed=True)
# Add edges with weights
for edge in self.edges_data:
from_node = self.str_to_int[edge['from']]
to_node = self.str_to_int[edge['to']]
weight = edge['weight']
self.graph.add_edge(from_node, to_node, weight)
def get_best_next_step(self, current_step_name):
"""
Find the best next step from the current position to reach 'close_deal'.
Args:
current_step_name: String name of the current step
Returns:
Tuple of (next_step_name, next_step_text) for the optimal next step
"""
# Find integer ID of current step
current_id = self.str_to_int[current_step_name]
# Run Bellman-Ford from current step
distances = bellman_ford_list(self.graph, current_id)
if distances is None:
raise ValueError("Negative cycle detected in the sales script graph!")
# Find the close_deal node ID
close_deal_id = self.str_to_int['close_deal']
# If we're already at close_deal, return it
if current_id == close_deal_id:
return current_step_name, self.node_text[current_step_name]
# Find the best immediate next step
# Look at all neighbors of current node and pick the one with shortest total distance to close_deal
adj_list = self.graph.get_list()
best_next_id = None
best_total_distance = float('inf')
for neighbor_id, edge_weight in adj_list[current_id]:
# Compute distance from this neighbor to close_deal
neighbor_distances = bellman_ford_list(self.graph, neighbor_id)
to_close = neighbor_distances[close_deal_id]
total_distance = edge_weight + to_close
if total_distance < best_total_distance:
best_total_distance = total_distance
best_next_id = neighbor_id
if best_next_id is None:
raise ValueError(f"No path found from '{current_step_name}' to 'close_deal'")
# Convert back to string name and get text
next_step_name = self.int_to_str[best_next_id]
next_step_text = self.node_text[next_step_name]
return next_step_name, next_step_text
if __name__ == "__main__":
# Simulate a conversation path
engine = SalesEngine()
current_step = "start"
print(f"Starting sales conversation at: {current_step}")
print(f">>> {engine.node_text[current_step]}\n")
step_count = 0
max_steps = 10 # Safety limit to prevent infinite loops
while current_step != "close_deal" and step_count < max_steps:
# Get the best next step
next_step, next_text = engine.get_best_next_step(current_step)
print(f"Best next move: {next_step}")
print(f">>> {next_text}\n")
current_step = next_step
step_count += 1
if current_step == "close_deal":
print("[SUCCESS] Successfully reached the deal closure!")
else:
print("[WARNING] Reached maximum steps without closing the deal.")