Skip to content

Commit

Permalink
Merge branch 'local-ai'
Browse files Browse the repository at this point in the history
  • Loading branch information
satellitecomponent committed Feb 5, 2024
2 parents d2cef09 + e8a4c05 commit 6f8818d
Show file tree
Hide file tree
Showing 10 changed files with 655 additions and 250 deletions.
101 changes: 57 additions & 44 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@

<div ondragover="dragOverHandler(event);" ondrop="dropHandler(event);">
<svg id="svg_bg" viewBox="-128 -128 256 256" width="100%" height="100vh" top="0" left="0" position="fixed">
<title>Mandelbrot</title>
<g id="viewmatrix">
<g id="bg" />
<path id="mousePath" d="" fill="none" stroke="rgb(50 51 62 / 80%)" stroke-width="0.01" />
Expand Down Expand Up @@ -292,8 +291,9 @@
<!-- Fourth tab content here -->
<div class="submenu">
<!--<div>
<button id="ai-cursor-button">Enable Ai Cursor</button>
</div>-->
<button id="ai-cursor-button">Enable Ai Cursor</button>
</div>-->
<br />
<div class="flex-container">
<div class="inline-container" title="Enable Local Ai Features">
<input type="checkbox" id="localLLM">
Expand Down Expand Up @@ -330,10 +330,6 @@
</div>
</div>
<br />
<input type="checkbox" id="local-embeddings-checkbox">
<label for="local-embeddings-checkbox">: Local Embeddings</label>
<br />
<br />
<div class="api-container">
<div class="api-inputs">
<div>
Expand Down Expand Up @@ -407,6 +403,59 @@
</div>
</div>

<div id="tabExtract" class="tabcontent">
<!-- Extract tab content here -->
<div class="submenu">
<div style="display: flex; justify-content: space-evenly; align-items: center;">
<label for="embeddingsModelSelect">Embeddings:</label><br>
<div class="dropdown-container">
<select id="embeddingsModelSelect" class="model-selector custom-select" onchange="handleEmbeddingsSelection(this)">
<option value="text-embedding-3-small">text-embedding-3-small</option>
<option value="text-embedding-3-large">text-embedding-3-large</option>
<option value="text-embedding-ada-002">text-embedding-ada-002</option>
<option value="local-embeddings">Local Embeddings</option>
</select>
</div>
</div>
<br>
<!-- Hide the original local embeddings checkbox -->
<input type="checkbox" id="local-embeddings-checkbox" style="display: none;">
<label for="local-embeddings-checkbox" style="display: none;">: Local Embeddings</label>
<label for="inputKeyExtract">Key:</label><br>
<input type="text" id="inputKeyExtract" name="inputKeyExtract" title="Set Title of Document"><br>
<label for="inputTextExtract">Text:</label><br>
<textarea id="inputTextExtract" rows="10" cols="50" class="zettelkasten" title="Plain Text of Document"></textarea><br>
<div class="button-container">
<button id="chunkAndStoreButton" class="linkbuttons" title="Send Text to Embeddings Database">Store Text</button>
<button onclick="deleteSelectedKeys()" class="linkbuttons" title="Delete Document from Embeddings Database">Delete Key(s)</button>
</div>
<div id="key-list" class="scrollable-list" title="Embedded Documents">
<!-- Stored keys will be dynamically added here -->
</div>
<!--<input type="file" id="fileInput" />
<button id="fileUploadButton" onclick="promptForFileUpload()">Upload Files</button>-->
<br />
<div class="settingsSlider centered" style="margin-bottom: 10px;" title="Number of Embedded Document Snippets to Retrieve for AI Response">
<label for="topN">Top <span id="topNValue">5</span> Webpage Excerpts</label>
<input type="range" id="topNSlider" name="topN" min="1" max="100" value="5">
</div>
<div class="gridLayout">

<div class="settingsSlider" title="Size of Document Snippets (Set Before Embedding">
<label for="maxChunkSizeSlider">Chunk Size: <br /><span id="maxChunkSizeValue"></span></label>
<input type="range" min="1" max="4096" value="1024" class="slider" id="maxChunkSizeSlider">
</div>

<div class="settingsSlider" title="Overlap Between Document Snippets (Set Before Embedding)">
<label for="overlapSizeSlider">Overlap:<br /><span id="overlapSizeDisplay">10</span></label>
<input type="range" id="overlapSizeSlider" name="overlapSize" min="1" max="100" value="10">
</div>

</div>
</div>
</div>


<div id="tab2" class="tabcontent">
<!-- Second tab content here -->
<div class="submenu">
Expand Down Expand Up @@ -510,42 +559,6 @@
</div>
</div>

<div id="tabExtract" class="tabcontent">
<!-- Extract tab content here -->
<div class="submenu">
<label for="inputKeyExtract">Key:</label><br>
<input type="text" id="inputKeyExtract" name="inputKeyExtract" title="Set Title of Document"><br>
<label for="inputTextExtract">Text:</label><br>
<textarea id="inputTextExtract" rows="10" cols="50" class="zettelkasten" title="Plain Text of Document"></textarea><br>
<div class="button-container">
<button id="chunkAndStoreButton" class="linkbuttons" title="Send Text to Embeddings Database">Store Text</button>
<button onclick="deleteSelectedKeys()" class="linkbuttons" title="Delete Document from Embeddings Database">Delete Key(s)</button>
</div>
<div id="key-list" class="scrollable-list" title="Embedded Documents">
<!-- Stored keys will be dynamically added here -->
</div>
<!--<input type="file" id="fileInput" />
<button id="fileUploadButton" onclick="promptForFileUpload()">Upload Files</button>-->
<br />
<div class="settingsSlider centered" style="margin-bottom: 10px;" title="Number of Embedded Document Snippets to Retrieve for AI Response">
<label for="topN">Top <span id="topNValue">5</span> Webpage Excerpts</label>
<input type="range" id="topNSlider" name="topN" min="1" max="100" value="5">
</div>
<div class="gridLayout">

<div class="settingsSlider" title="Size of Document Snippets (Set Before Embedding">
<label for="maxChunkSizeSlider">Chunk Size: <br /><span id="maxChunkSizeValue"></span></label>
<input type="range" min="1" max="4096" value="1024" class="slider" id="maxChunkSizeSlider">
</div>

<div class="settingsSlider" title="Overlap Between Document Snippets (Set Before Embedding)">
<label for="overlapSizeSlider">Overlap:<br /><span id="overlapSizeDisplay">10</span></label>
<input type="range" id="overlapSizeSlider" name="overlapSize" min="1" max="100" value="10">
</div>

</div>
</div>
</div>

<div id="tab6" class="tabcontent">
<div class="submenu">
Expand Down Expand Up @@ -817,7 +830,7 @@
<line x1="4" y1="18" x2="20" y2="18" stroke="currentColor" stroke-width="2"></line>
</svg>

<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="#A6A6A6" class="bi bi-sliders2" viewBox="0 0 16 16" display="none">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="#686868" class="bi bi-sliders2" viewBox="0 0 16 16" display="none">
<path fill-rule="evenodd" d="M10.5 1a.5.5 0 0 1 .5.5v4a.5.5 0 0 1-1 0V4H1.5a.5.5 0 0 1 0-1H10V1.5a.5.5 0 0 1 .5-.5ZM12 3.5a.5.5 0 0 1 .5-.5h2a.5.5 0 0 1 0 1h-2a.5.5 0 0 1-.5-.5Zm-6.5 2A.5.5 0 0 1 6 6v1.5h8.5a.5.5 0 0 1 0 1H6V10a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5ZM1 8a.5.5 0 0 1 .5-.5h2a.5.5 0 0 1 0 1h-2A.5.5 0 0 1 1 8Zm9.5 2a.5.5 0 0 1 .5.5v4a.5.5 0 0 1-1 0V13H1.5a.5.5 0 0 1 0-1H10v-1.5a.5.5 0 0 1 .5-.5Zm1.5 2.5a.5.5 0 0 1 .5-.5h2a.5.5 0 0 1 0 1h-2a.5.5 0 0 1-.5-.5Z" />
</svg>

Expand Down
111 changes: 82 additions & 29 deletions js/dropdown/dropdown_v2_0_1.js
Original file line number Diff line number Diff line change
Expand Up @@ -302,40 +302,75 @@ function addEventListenersToCustomDropdown(select, aiNode) {
}

document.addEventListener('DOMContentLoaded', function () {
// Setup for all existing custom-selects
let selects = document.querySelectorAll('select.custom-select');
selects.forEach(setupCustomDropdown);
selects.forEach(select => setupModelSelect(select, select.id === 'embeddingsModelSelect'));
});

let modelSelect = document.querySelector('#model-select');
if (modelSelect) {
handleModelSelectChange(modelSelect); // Add specific change listener
function setupModelSelect(selectElement, isEmbeddingsSelect = false) {
if (selectElement) {
setupCustomDropdown(selectElement);

// Restore selection from local storage
const storedValue = localStorage.getItem('selectedModel');
const storedValue = localStorage.getItem(selectElement.id);
if (storedValue) {
modelSelect.value = storedValue;

// Update the custom dropdown display to show the stored value
let selectedDiv = modelSelect.parentNode.querySelector('.select-replacer > div');
if (selectedDiv) {
selectedDiv.innerText = modelSelect.options[modelSelect.selectedIndex].innerText;
selectElement.value = storedValue;
updateSelectedOptionDisplay(selectElement);
if (isEmbeddingsSelect) {
checkLocalEmbeddingsCheckbox(selectElement);
}
}

// Set change event listener for caching selected value and updating display
selectElement.addEventListener('change', function () {
localStorage.setItem(this.id, this.value);
updateSelectedOptionDisplay(this);
if (isEmbeddingsSelect) {
checkLocalEmbeddingsCheckbox(this);
}
});
}
});
}

function updateSelectedOptionDisplay(selectElement) {
// Update the custom dropdown display to show the selected value
let selectedDiv = selectElement.parentNode.querySelector('.select-replacer > div');
if (selectedDiv) {
selectedDiv.innerText = selectElement.options[selectElement.selectedIndex].innerText;
}

// Update highlighting in the custom dropdown options
let optionsReplacer = selectElement.parentNode.querySelector('.options-replacer');
if (optionsReplacer) {
let optionDivs = optionsReplacer.querySelectorAll('div');
optionDivs.forEach(div => {
if (div.getAttribute('data-value') === selectElement.value) {
div.classList.add('selected');
} else {
div.classList.remove('selected');
}
});
}
}

function handleModelSelectChange(selectElement) {
selectElement.addEventListener('change', function () {
// Save the selected value in local storage
localStorage.setItem('selectedModel', this.value);
function checkLocalEmbeddingsCheckbox(selectElement) {
const localEmbeddingsCheckbox = document.getElementById('local-embeddings-checkbox');

// If you have a corresponding custom dropdown display, update it
const customDisplayDiv = this.parentNode.querySelector('.select-replacer > div');
if (customDisplayDiv) {
customDisplayDiv.innerText = this.options[this.selectedIndex].innerText;
}
});
localEmbeddingsCheckbox.checked = selectElement.value === 'local-embeddings';
}

function handleEmbeddingsSelection(selectElement) {
const localEmbeddingsCheckbox = document.getElementById('local-embeddings-checkbox');

if (selectElement.value === 'local-embeddings') {
// Check the hidden checkbox when local embeddings is selected
localEmbeddingsCheckbox.checked = true;
} else {
// Uncheck the hidden checkbox for other selections
localEmbeddingsCheckbox.checked = false;
}

// Additional logic here if needed, e.g., saving the selection to localStorage
}

// Function for custom slider background
Expand Down Expand Up @@ -768,14 +803,32 @@ setRenderQuality(getQuality());
});


document.getElementById("exponent").addEventListener("input", (e) => {
let v = e.target.value * 1;
mand_step = (z, c) => {
return z.ipow(v).cadd(c);
}
document.getElementById("exponent_value").textContent = v;
})
document.getElementById("exponent").addEventListener("input", (e) => {
let v = e.target.value * 1; // Convert to number
mand_step = (z, c) => {
return z.ipow(v).cadd(c);
};
document.getElementById("exponent_value").textContent = v;

// Update maxDist based on exponent
settings.maxDist = getMaxDistForExponent(v);
});


function getMaxDistForExponent(exponent) {
const exponentToMaxDist = {
1: 4,
2: 4,
3: 1.5,
4: 1.25,
5: 1,
6: 1,
7: 1,
8: 1
};

return exponentToMaxDist[exponent] || 4; // default to 4 if no mapping found
}

// Function to update the flashlight strength and its display
function updateFlashlightStrength() {
Expand Down
46 changes: 27 additions & 19 deletions js/dropdown/savenet.js
Original file line number Diff line number Diff line change
Expand Up @@ -165,10 +165,6 @@ function updateSavedNetworks() {
// Call updateSavedNetworks on page load to display previously saved networks
updateSavedNetworks();

document.getElementById("load-button").addEventListener("click", function () {
loadnet(document.getElementById("save-or-load").value, true);
});

let container = document.getElementById("saved-networks-container");

// Prevent default drag behaviors
Expand Down Expand Up @@ -266,6 +262,7 @@ function clearnet() {
while (edges.length > 0) {
edges[edges.length - 1].remove();
}
edgeDirectionalityMap.clear();

// Remove all nodes
while (nodes.length > 0) {
Expand All @@ -279,19 +276,6 @@ function clearnet() {
window.myCodemirror.setValue('');
}

//this is a quick fix to retain textarea height, the full fix requires all event listeners to be attatched to each node.

/* function adjustTextareaHeightToContent(nodes) {
for (let node of nodes) {
let textarea = node.content.querySelector('textarea');
if (textarea) {
textarea.style.height = 'auto'; // Temporarily shrink to content
const maxHeight = 300; // Maximum height in pixels
textarea.style.height = Math.min(textarea.scrollHeight, maxHeight) + 'px'; // Set to full content height or max height
}
}
} */

function restoreAdditionalSaveObjects(d) {

let savedViewsElement = d.querySelector("#saved-views");
Expand All @@ -318,6 +302,11 @@ function restoreAdditionalSaveObjects(d) {
restoreInputValues();
}

document.getElementById("load-button").addEventListener("click", function () {
loadnet(document.getElementById("save-or-load").value, true);

});

function loadnet(text, clobber, createEdges = true) {
if (clobber) {
clearnet();
Expand Down Expand Up @@ -346,12 +335,13 @@ function loadnet(text, clobber, createEdges = true) {
if (n.dataset.init === "window")
rewindowify(node);
}
populateDirectionalityMap(d, nodeMap);

for (let n of newNodes) {
htmlnodes_parent.appendChild(n.content);
}

for (let n of newNodes) {
n.init(nodeMap); // Initialize the node

reconstructSavedNode(n); // Reconstruct the saved node
}

Expand All @@ -362,6 +352,24 @@ function loadnet(text, clobber, createEdges = true) {
}
}

function populateDirectionalityMap(d, nodeMap) {
const nodes = Array.from(d.children);
nodes.forEach(nodeElement => {
if (nodeElement.hasAttribute('data-edges')) {
const edgesData = JSON.parse(nodeElement.getAttribute('data-edges'));
edgesData.forEach(edgeData => {
const edgeKey = edgeData.edgeKey;
if (!edgeDirectionalityMap.has(edgeKey)) {
edgeDirectionalityMap.set(edgeKey, {
start: nodeMap[edgeData.directionality.start],
end: nodeMap[edgeData.directionality.end]
});
}
});
}
});
}

function reconstructSavedNode(node) {
// Restore the title
let titleInput = node.content.querySelector('.title-input');
Expand Down
Loading

0 comments on commit 6f8818d

Please sign in to comment.