-
Notifications
You must be signed in to change notification settings - Fork 1
/
multiverse.js
156 lines (128 loc) · 4.97 KB
/
multiverse.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
// multiverse.js
// Conversation tree variables
let conversationRoot = null;
let currentConversationNode = null;
// Function to initialize conversation tree
function initializeConversationTree() {
conversationRoot = null;
currentConversationNode = null;
}
// Function to generate a unique ID for each node
function generateUniqueId() {
return '_' + Math.random().toString(36).substr(2, 9);
}
// Define the ConversationNode class
function ConversationNode(prompt, response = null, parent = null) {
this.id = generateUniqueId();
this.prompt = prompt;
this.response = response;
this.parent = parent;
this.children = [];
}
// Function to add a message to the conversation tree
function addMessageToConversationTree(role, content) {
if (role === 'user') {
// Create new node with just the prompt
const newNode = new ConversationNode(content, null, currentConversationNode);
if (currentConversationNode) {
currentConversationNode.children.push(newNode);
} else {
conversationRoot = newNode;
}
currentConversationNode = newNode;
} else if (role === 'assistant') {
// Add response to current node
currentConversationNode.response = content;
}
// Update the multiverse visualization
renderMultiverse();
}
// Function to render the multiverse visualization
function renderMultiverse() {
const multiverseDiv = document.querySelector('.multiverse');
if (!multiverseDiv) return;
// Clear existing content
multiverseDiv.innerHTML = '';
if (!conversationRoot) return;
// Use a recursive function to render the tree
const treeContainer = document.createElement('div');
treeContainer.className = 'tree-container';
function renderNode(node, parentElement) {
const nodeContainer = document.createElement('div');
nodeContainer.className = 'node-container';
const nodeElement = document.createElement('div');
nodeElement.className = 'node';
nodeElement.textContent = `Q: ${node.prompt}${node.response ? '\nA: ' + node.response : ''}`;
nodeElement.dataset.nodeId = node.id;
// Check if this node is in the current conversation path
let checkNode = currentConversationNode;
while (checkNode) {
if (checkNode === node) {
nodeElement.classList.add('context-node');
break;
}
checkNode = checkNode.parent;
}
// Highlight the current node
if (node === currentConversationNode) {
nodeElement.classList.add('current-node');
}
nodeElement.addEventListener('click', () => {
selectConversationNode(node);
});
nodeContainer.appendChild(nodeElement);
if (node.children.length > 0) {
const childrenContainer = document.createElement('div');
childrenContainer.className = 'children-container';
node.children.forEach(child => {
renderNode(child, childrenContainer);
});
nodeContainer.appendChild(childrenContainer);
}
parentElement.appendChild(nodeContainer);
}
renderNode(conversationRoot, treeContainer);
multiverseDiv.appendChild(treeContainer);
}
// Function to select a node in the conversation tree
function selectConversationNode(node) {
currentConversationNode = node;
renderMultiverse();
// Update the chat area to reflect the current conversation path
renderChatFromConversationNode();
}
// Function to render the chat area from the current conversation node
function renderChatFromConversationNode() {
const responseDiv = document.getElementById('response');
if (!responseDiv) return;
// Clear existing messages
responseDiv.innerHTML = '';
// Get messages from root to current node
const messages = [];
let node = currentConversationNode;
while (node) {
messages.unshift(node);
node = node.parent;
}
messages.forEach(node => {
// Create user message
const userMessageDiv = document.createElement('div');
userMessageDiv.className = 'message user-message';
userMessageDiv.textContent = node.prompt;
responseDiv.appendChild(userMessageDiv);
// Create AI message if it exists
if (node.response) {
const aiMessageDiv = document.createElement('div');
aiMessageDiv.className = 'message ai-message';
aiMessageDiv.innerHTML = marked.parse(node.response);
responseDiv.appendChild(aiMessageDiv);
}
});
// Add auto-scroll
responseDiv.scrollTop = responseDiv.scrollHeight;
}
// Initialize the conversation tree
initializeConversationTree();
// Expose functions to be used by app.js
window.addMessageToConversationTree = addMessageToConversationTree;
window.initializeConversationTree = initializeConversationTree;