Spaces:
Sleeping
Sleeping
| 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.") | |