<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Modelium Designer</title>
<link rel="stylesheet" href="https://unpkg.com/vis-network/styles/vis-network.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css">
<style>
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
margin: 0;
padding: 0;
display: flex;
height: 100vh;
background-color: #f0f0f0; /* Light gray background */
color: #333; /* Dark gray text */
}
.main-container {
display: flex;
height: 100%; /* Make the main container fill the entire viewport */
}
#modelium-container {
flex-grow: 1;
border: 1px solid #ccc;
background-color: #fff; /* White network container */
}
#sidebar {
width: 300px;
background-color: #fff; /* White sidebar */
padding: 20px;
overflow-y: auto;
display: flex;
flex-direction: column; /* Stack elements vertically */
box-shadow: -2px 0 5px rgba(0, 0, 0, 0.1); /* Subtle shadow */
}
#sidebar-menu {
flex-grow: 1; /* Allow the menu to take up available space */
padding-bottom: 20px; /* Add padding at the bottom */
}
.node-type {
padding: 10px;
border: 1px solid #ccc;
margin-bottom: 5px;
cursor: pointer;
background-color: #eee;
border-radius: 5px; /* Rounded corners */
transition: background-color 0.2s ease; /* Smooth transition for hover effect */
}
.node-type:hover {
background-color: #ddd;
}
#properties {
margin-top: 20px;
}
#node-properties h3 {
margin-top: 0;
color: #333; /* Darker gray for headings */
font-weight: bold;
}
#node-properties label {
display: block;
margin-bottom: 5px;
color: #333;
}
#node-properties input,
#node-properties textarea,
#node-properties select {
width: 100%;
padding: 8px;
margin-bottom: 10px;
border: 1px solid #ccc;
border-radius: 5px;
background-color: #f8f8f8; /* Light gray input background */
color: #333;
}
.modelium-to-model {
color: #f39c12;
width: 3px;
}
.modelium-to-model .vis-edge .vis-line {
stroke-dasharray: 5, 5;
}
#sidebar button {
padding: 8px 15px;
background-color: #3498db; /* Blue button */
color: white;
border: none;
cursor: pointer;
border-radius: 5px;
margin-bottom: 10px;
transition: background-color 0.2s ease;
}
#sidebar button:hover {
background-color: #2980b9; /* Darker blue on hover */
}
.node-icon {
position: absolute;
top: -10px;
right: -10px;
width: 20px;
height: 20px;
background-size: cover;
}
.tools-icon {
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAjklEQVR4nO3UQQqDMBCF4X+yCXgQ7yEIgu4KvULXbQW9/26KCSWSlEKpC1cDswj5mMwbQoxxwWtaawvr7+xYa21pCYEHjtivtTiDz5RSqfSctR0X5JzPD+NKqTp0xLRjWlzQe7+WUnZCiA0ppQ0hxK6UsvfeX//6XT/ihjue0Fq71VrXEMKhtfZijLl9Mz8BmI0StacvT10AAAAASUVORK5CYII=');
}
.parallel-icon {
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAV0lEQVR4nGNgGAWjYKiD/wDMQKwCZD4TsS4k1jByDWMiRhGxLiTFMCZiFRHrQlINYyJGEbEuJMcwJkIKiXUhuYYx4VNIiovINYyJkEJiXUiJYaNgZAMAYnAb1CJ5IcEAAAAASUVORK5CYII=');
}
#sidebar .vis-network {
display: none; /* Hide the Vis.js network from the sidebar */
}
</style>
</head>
<body>
<div class="main-container">
<div id="modelium-container"></div>
<div id="sidebar">
<div id="sidebar-menu">
<h2>Elements</h2>
<div class="node-type" draggable="true" data-type="modelium">Modelium</div>
<div class="node-type" draggable="true" data-type="model">Model</div>
<div class="node-type" draggable="true" data-type="result">Result</div>
<div class="node-type" draggable="true" data-type="return">Return</div>
<h2>Display Options</h2>
<label><input type="checkbox" id="show-prompt" onchange="updateModelLabels()"> Show Prompt</label><br>
<label><input type="checkbox" id="show-system-instructions" onchange="updateModelLabels()"> Show System Instructions</label><br>
<label><input type="checkbox" id="show-tools" onchange="updateModelLabels()"> Show Tools</label><br>
<label><input type="checkbox" id="show-model-type" onchange="updateModelLabels()"> Show Model Type</label><br>
</div>
<div id="properties">
<h2>Properties</h2>
<div id="node-properties"></div>
</div>
<button id="generate-description-button" onclick="generateAndDisplayStructuredDescription()">Generate Structured Description</button>
</div>
</div>
<script src="https://unpkg.com/vis-network/standalone/umd/vis-network.min.js"></script>
<script>
let nodes = new vis.DataSet([]);
let edges = new vis.DataSet([]);
let network = null;
let lastNodeId = 0;
function initNetwork() {
const container = document.getElementById('modelium-container');
const data = { nodes, edges };
const options = {
manipulation: {
enabled: true,
addNode: false,
addEdge: function (edgeData, callback) {
if (edgeData.from !== edgeData.to) {
const fromNode = nodes.get(edgeData.from);
const toNode = nodes.get(edgeData.to);
if (fromNode.type === 'modelium' && toNode.type === 'model' && toNode.parentId === fromNode.id) {
edgeData.classes = 'modelium-to-model';
}
callback(edgeData);
}
}
},
nodes: {
shape: 'box',
size: 30,
font: { size: 12, color: '#ffffff' },
borderWidth: 2,
shadow: true,
color: {
'modelium': {
background: '#f1c40f',
border: '#f39c12'
},
'model': {
background: '#3498db',
border: '#2980b9'
},
'result': {
background: '#2ecc71',
border: '#27ae60'
},
'return': {
background: '#27ae60',
border: '#1e8449'
}
}
},
edges: {
arrows: {
to: { enabled: true, scaleFactor: 1 },
middle: { enabled: true, scaleFactor: 0.5 }
},
smooth: { type: 'dynamic' },
color: { color: '#848484', highlight: '#848484', hover: '#848484' },
width: 2
},
physics: { enabled: false },
interaction: { hover: true }
};
network = new vis.Network(container, data, options);
network.on("click", function (params) {
if (params.nodes.length > 0) {
showNodeProperties(params.nodes[0]);
} else {
clearProperties();
}
});
setupDragAndDrop();
network.on("edgeAdded", function (params) {
adjustModeliumStructure();
});
network.on("edgeRemoved", function (params) {
adjustModeliumStructure();
});
}
function setupDragAndDrop() {
const container = document.getElementById('modelium-container');
container.ondragover = function (e) { e.preventDefault(); };
container.ondrop = function (e) {
e.preventDefault();
const type = e.dataTransfer.getData("text");
const pos = network.DOMtoCanvas({ x: e.clientX, y: e.clientY });
addNewNode(type, pos.x, pos.y);
};
const nodeTypes = document.getElementsByClassName('node-type');
for (let nodeType of nodeTypes) {
nodeType.ondragstart = function (e) {
e.dataTransfer.setData("text", this.dataset.type);
};
}
}
function addNewNode(type, x, y) {
if (type === 'modelium') {
lastNodeId++;
const modeliumNode = {
id: lastNodeId,
label: 'Modelium',
x: x,
y: y,
type: 'modelium',
group: 'modelium',
chainLength: 1,
loopCount: 0,
parallelCount: 1,
modeliumType: 'standard',
structureDescription: "",
nestedModeliums: []
};
if (modeliumNode.parallelCount > 1) {
modeliumNode.shape = 'box';
modeliumNode.shapeProperties = { borderDashes: [5, 5] };
modeliumNode.icon = {
face: 'FontAwesome',
code: '\uf126',
size: 50,
color: '#000000'
};
}
nodes.add(modeliumNode);
createModeliumStructure(modeliumNode);
} else if (type === 'model') {
lastNodeId++;
let label = 'Model';
if (document.getElementById('show-prompt').checked) label += '\nPrompt: N/A';
if (document.getElementById('show-system-instructions').checked) label += '\nSys Instr: N/A';
if (document.getElementById('show-tools').checked) label += '\nTools: N/A';
if (document.getElementById('show-model-type').checked) label += '\nType: N/A';
const modelNode = {
id: lastNodeId,
label: label,
x: x,
y: y,
type: 'model',
group: 'model',
system_instructions: "",
prompts: "",
model_type: "",
tools: "none"
};
if (modelNode.tools !== 'none') {
modelNode.shape = 'box';
modelNode.shapeProperties = { borderDashes: [5, 5] };
modelNode.icon = {
face: 'FontAwesome',
code: '\uf0ad',
size: 50,
color: '#000000'
};
}
nodes.add(modelNode);
updateModelLabels(modelNode); // Update label after adding model node
} else if (type === 'result') {
lastNodeId++;
const resultNode = {
id: lastNodeId,
label: 'Result',
x: x,
y: y,
type: 'result',
group: 'result'
};
nodes.add(resultNode);
} else if (type === 'return') {
lastNodeId++;
const returnNode = {
id: lastNodeId,
label: 'Return',
x: x,
y: y,
type: 'return',
group: 'return'
};
nodes.add(returnNode);
}
}
function createModeliumStructure(modelium) {
const modelCount = modelium.chainLength * modelium.parallelCount;
const baseX = modelium.x;
const baseY = modelium.y + 100;
let firstModelIds = [];
let lastModelIds = [];
let resultNodeIds = [];
lastNodeId++;
const returnNode = {
id: lastNodeId,
label: 'Return',
type: 'return',
parentId: modelium.id,
x: baseX + (modelium.parallelCount * 150) / 2,
y: baseY + (modelium.chainLength + 1) * 100,
group: 'return'
};
nodes.add(returnNode);
for (let j = 0; j < modelium.parallelCount; j++) {
let lastModelId = modelium.id;
let xOffset = j * 150 - ((modelium.parallelCount - 1) * 75);
for (let i = 0; i < modelium.chainLength; i++) {
lastNodeId++;
const modelNode = {
id: lastNodeId,
label: 'Model',
type: 'model',
parentId: modelium.id,
x: baseX + xOffset,
y: baseY + (i * 100),
group: 'model',
system_instructions: "",
prompts: "",
model_type: "",
tools: "none"
};
if (document.getElementById('show-prompt').checked) modelNode.label += '\nPrompt: ' + (modelNode.prompts || 'N/A');
if (document.getElementById('show-system-instructions').checked) modelNode.label += '\nSys Instr: ' + (modelNode.system_instructions || 'N/A');
if (document.getElementById('show-tools').checked) modelNode.label += '\nTools: ' + (modelNode.tools || 'N/A');
if (document.getElementById('show-model-type').checked) modelNode.label += '\nType: ' + (modelNode.model_type || 'N/A');
if (modelNode.tools !== 'none') {
modelNode.shape = 'box';
modelNode.shapeProperties = { borderDashes: [5, 5] };
modelNode.icon = {
face: 'FontAwesome',
code: '\uf0ad',
size: 50,
color: '#000000'
};
}
nodes.add(modelNode);
if (i === 0) {
edges.add({
from: modelium.id,
to: modelNode.id,
classes: 'modelium-to-model'
});
firstModelIds.push(modelNode.id);
} else {
edges.add({
from: lastModelId,
to: modelNode.id
});
}
lastModelId = modelNode.id;
}
lastNodeId++;
const resultNode = {
id: lastNodeId,
label: 'Result',
type: 'result',
parentId: modelium.id,
x: baseX + xOffset,
y: baseY + (modelium.chainLength * 100),
group: 'result'
};
nodes.add(resultNode);
resultNodeIds.push(resultNode.id);
edges.add({
from: lastModelId,
to: resultNode.id
});
lastModelIds.push(resultNode.id);
}
resultNodeIds.forEach(resultNodeId => {
edges.add({
from: resultNodeId,
to: returnNode.id
});
});
if (modelium.modeliumType === 'chainLoop' && modelium.loopCount > 0) {
lastModelIds.forEach((lastModelId, index) => {
const firstModelId = firstModelIds[index];
edges.add({
id: `loop-${lastModelId}-${firstModelId}`,
from: lastModelId,
to: firstModelId,
smooth: {
type: 'curvedCW',
roundness: 0.3
},
label: `x${modelium.loopCount}`,
font: { size: 10, color: '#848484' },
color: { color: '#848484' },
dashes: [5, 5],
arrows: { to: { enabled: true, scaleFactor: 0.5 } }
});
});
}
modelium.structureDescription = generateStructuredDescription(modelium);
nodes.update(modelium);
}
function generateStructuredDescription(modelium) {
let schema = {
type: modelium.modeliumType,
name: modelium.label, // Include the name of the Modelium
chainLength: modelium.chainLength,
parallelCount: modelium.parallelCount,
loopCount: modelium.loopCount,
models: [],
results: [],
returns: [],
nestedModeliums: []
};
const childNodes = nodes.get({
filter: function (node) {
return node.parentId === modelium.id;
}
});
childNodes.forEach(node => {
switch (node.type) {
case 'model':
schema.models.push({
id: node.id,
systemInstructions: node.system_instructions,
prompts: node.prompts,
modelType: node.model_type,
tools: node.tools
});
break;
case 'result':
schema.results.push({ id: node.id });
break;
case 'return':
schema.returns.push({ id: node.id });
break;
case 'modelium':
// Recursively call generateStructuredDescription for nested Modeliums
schema.nestedModeliums.push(generateStructuredDescription(node));
break;
}
});
return schema;
}
function generateAndDisplayStructuredDescription() {
const modeliumNodes = nodes.get({
filter: function (node) {
return node.type === 'modelium';
}
});
if (modeliumNodes.length === 0) {
alert('No Modelium node found!');
return;
}
const rootModelium = modeliumNodes.reduce((prev, current) =>
(prev.y < current.y) ? prev : current
);
const structuredDescription = generateStructuredDescription(rootModelium);
document.getElementById('structureDescription').value = JSON.stringify(structuredDescription, null, 2);
}
function clearProperties() {
document.getElementById('node-properties').innerHTML = '';
}
function showNodeProperties(nodeId) {
const node = nodes.get(nodeId);
const propertiesDiv = document.getElementById('node-properties');
propertiesDiv.innerHTML = `<h3>${node.label} Properties</h3>`;
if (node.type === 'modelium') {
propertiesDiv.innerHTML += `
<label for="modeliumName">Name:</label><br>
<input type="text" id="modeliumName" value="${node.label}"><br>
<label for="chainLength">Chain Length:</label>
<input type="number" id="chainLength" value="${node.chainLength}" min="1"><br>
<label for="loopCount">Loop Count:</label>
<input type="number" id="loopCount" value="${node.loopCount}" min="0"><br>
<label for="parallelCount">Parallel Count:</label>
<input type="number" id="parallelCount" value="${node.parallelCount}" min="1"><br>
<label for="modeliumType">Modelium Type:</label><br>
<select id="modeliumType">
<option value="standard" ${node.modeliumType === 'standard' ? 'selected' : ''}>Standard</option>
<option value="chainLoop" ${node.modeliumType === 'chainLoop' ? 'selected' : ''}>Chain Loop</option>
<option value="hierarchical" ${node.modeliumType === 'hierarchical' ? 'selected' : ''}>Hierarchical</option>
</select><br>
<button onclick="updateModeliumProperties(${nodeId})">Update Properties</button><br>
<button onclick="generateAndDisplayStructuredDescription(${nodeId})">Generate Structured Description</button><br>
<label for="structureDescription">Structure Description:</label><br>
<textarea id="structureDescription" readonly style="width: 100%; height: 200px;"></textarea><br>
`;
} else if (node.type === 'model') {
propertiesDiv.innerHTML += `
<label for="system_instructions">System Instructions:</label><br>
<textarea id="system_instructions">${node.system_instructions || ''}</textarea><br>
<label for="prompts">Prompts:</label><br>
<textarea id="prompts">${node.prompts || ''}</textarea><br>
<label for="model_type">Model Type:</label><br>
<input type="text" id="model_type" value="${node.model_type || ''}"><br>
<label for="tools">Tools:</label><br>
<select id="tools">
<option value="none" ${node.tools === 'none' ? 'selected' : ''}>None</option>
<option value="all" ${node.tools === 'all' ? 'selected' : ''}>All</option>
<option value="chooser" ${node.tools === 'chooser' ? 'selected' : ''}>Chooser</option>
</select><br>
<button onclick="updateModelProperties(${nodeId})">Update</button>
`;
}
}
function updateModeliumProperties(nodeId) {
const node = nodes.get(nodeId);
node.label = document.getElementById('modeliumName').value;
node.chainLength = parseInt(document.getElementById('chainLength').value);
node.loopCount = parseInt(document.getElementById('loopCount').value);
node.parallelCount = parseInt(document.getElementById('parallelCount').value);
node.modeliumType = document.getElementById('modeliumType').value;
nodes.update(node);
// Remove existing child nodes and edges
const childNodes = nodes.get({
filter: function (node) {
return node.parentId === nodeId;
}
});
nodes.remove(childNodes.map(node => node.id));
edges.remove(edges.getIds({
filter: function (edge) {
return childNodes.some(node => node.id === edge.from || node.id === edge.to);
}
}));
// Recreate the structure based on updated properties
createModeliumStructure(node);
}
function updateModelProperties(nodeId) {
const node = nodes.get(nodeId);
node.system_instructions = document.getElementById('system_instructions').value;
node.prompts = document.getElementById('prompts').value;
node.model_type = document.getElementById('model_type').value;
node.tools = document.getElementById('tools').value;
nodes.update(node);
// Update the label after updating properties
updateModelLabels(node);
}
// Function to adjust the Modelium structure for better visualization
function adjustModeliumStructure() {
// You can implement various logic here based on your visualization needs
// Example:
// 1. Use a layout algorithm (e.g., from vis.js or other libraries)
// 2. Manually reposition nodes based on their connections and depth
// 3. Adjust edge smoothness or curvature for better appearance
// For now, a simple repositioning example:
const allNodes = nodes.get();
let maxX = 0;
allNodes.forEach(node => {
if (node.x > maxX) {
maxX = node.x;
}
});
allNodes.forEach(node => {
node.x = maxX + 100;
nodes.update(node);
});
}
function updateModelLabels(node = null) {
const showPrompt = document.getElementById('show-prompt').checked;
const showSystemInstructions = document.getElementById('show-system-instructions').checked;
const showTools = document.getElementById('show-tools').checked;
const showModelType = document.getElementById('show-model-type').checked;
if (!node) { // If no specific node is passed, update all model nodes
const modelNodes = nodes.get({ filter: n => n.type === 'model' });
modelNodes.forEach(modelNode => {
updateModelLabels(modelNode); // Call recursively to update each model node
});
return;
}
let label = 'Model';
if (showPrompt) label += '\nPrompt: ' + (node.prompts || 'N/A');
if (showSystemInstructions) label += '\nSys Instr: ' + (node.system_instructions || 'N/A');
if (showTools) label += '\nTools: ' + (node.tools || 'N/A');
if (showModelType) label += '\nType: ' + (node.model_type || 'N/A');
node.label = label;
nodes.update(node);
}
initNetwork();
</script>
</body>
</html>
1 Like
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Modelium Designer</title>
<link rel="stylesheet" href="https://unpkg.com/vis-network/styles/vis-network.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css">
<style>
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
margin: 0;
padding: 0;
display: flex;
height: 100vh;
background-color: #181818; /* Dark gray background */
color: #eee; /* Light gray text */
}
.main-container {
display: flex;
height: 100%;
}
#modelium-container {
flex-grow: 1;
border: 1px solid #333;
background-color: #282828; /* Darker gray network container */
}
#sidebar {
width: 300px;
background-color: #282828; /* Darker gray sidebar */
padding: 20px;
overflow-y: auto;
display: flex;
flex-direction: column;
box-shadow: -2px 0 5px rgba(0, 0, 0, 0.2);
}
#sidebar-menu {
flex-grow: 1;
padding-bottom: 20px;
}
.node-type {
padding: 10px;
border: 1px solid #333;
margin-bottom: 5px;
cursor: pointer;
background-color: #333;
border-radius: 5px;
transition: background-color 0.2s ease;
}
.node-type:hover {
background-color: #444;
}
#properties {
margin-top: 20px;
}
#node-properties h3 {
margin-top: 0;
color: #eee;
font-weight: bold;
}
#node-properties label {
display: block;
margin-bottom: 5px;
color: #eee;
}
#node-properties input,
#node-properties textarea,
#node-properties select {
width: 100%;
padding: 8px;
margin-bottom: 10px;
border: 1px solid #555;
border-radius: 5px;
background-color: #222; /* Darker gray input background */
color: #eee;
}
.modelium-to-model {
color: #f39c12;
width: 3px;
}
.modelium-to-model .vis-edge .vis-line {
stroke-dasharray: 5, 5;
}
#sidebar button {
padding: 8px 15px;
background-color: #3498db;
color: white;
border: none;
cursor: pointer;
border-radius: 5px;
margin-bottom: 10px;
transition: background-color 0.2s ease;
}
#sidebar button:hover {
background-color: #2980b9;
}
.node-icon {
position: absolute;
top: -10px;
right: -10px;
width: 20px;
height: 20px;
background-size: cover;
}
.tools-icon {
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAjklEQVR4nO3UQQqDMBCF4X+yCXgQ7yEIgu4KvULXbQW9/26KCSWSlEKpC1cDswj5mMwbQoxxwWtaawvr7+xYa21pCYEHjtivtTiDz5RSqfSctR0X5JzPD+NKqTp0xLRjWlzQe7+WUnZCiA0ppQ0hxK6UsvfeX//6XT/ihjue0Fq71VrXEMKhtfZijLl9Mz8BmI0StacvT10AAAAASUVORK5CYII=');
}
.parallel-icon {
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAV0lEQVR4nGNgGAWjYKiD/wDMQKwCZD4TsS4k1jByDWMiRhGxLiTFMCZiFRHrQlINYyJGEbEuJMcwJkIKiXUhuYYx4VNIiovINYyJkEJiXUiJYaNgZAMAYnAb1CJ5IcEAAAAASUVORK5CYII=');
}
#sidebar .vis-network {
display: none;
}
/* Node Colors */
.vis-node.modelium {
background-color: #f1c40f; /* Yellowish */
border-color: #f39c12; /* Darker yellow */
}
.vis-node.model {
background-color: #3498db; /* Blue */
border-color: #2980b9; /* Darker blue */
}
.vis-node.result {
background-color: #2ecc71; /* Green */
border-color: #27ae60; /* Darker green */
}
.vis-node.return {
background-color: #27ae60; /* Green */
border-color: #1e8449; /* Darker green */
}
/* Node Text Color */
.vis-node .vis-label {
color: #000; /* Black */
}
</style>
</head>
<body>
<div class="main-container">
<div id="modelium-container"></div>
<div id="sidebar">
<div id="sidebar-menu">
<h2>Elements</h2>
<div class="node-type" draggable="true" data-type="modelium">Modelium</div>
<div class="node-type" draggable="true" data-type="model">Model</div>
<div class="node-type" draggable="true" data-type="result">Result</div>
<div class="node-type" draggable="true" data-type="return">Return</div>
<h2>Display Options</h2>
<label><input type="checkbox" id="show-prompt" onchange="updateModelLabels()"> Show Prompt</label><br>
<label><input type="checkbox" id="show-system-instructions" onchange="updateModelLabels()"> Show System Instructions</label><br>
<label><input type="checkbox" id="show-tools" onchange="updateModelLabels()"> Show Tools</label><br>
<label><input type="checkbox" id="show-model-type" onchange="updateModelLabels()"> Show Model Type</label><br>
</div>
<div id="properties">
<h2>Properties</h2>
<div id="node-properties"></div>
</div>
<button id="generate-description-button" onclick="generateAndDisplayStructuredDescription()">Generate Structured Description</button>
</div>
</div>
<script src="https://unpkg.com/vis-network/standalone/umd/vis-network.min.js"></script>
<script>
let nodes = new vis.DataSet([]);
let edges = new vis.DataSet([]);
let network = null;
let lastNodeId = 0;
function initNetwork() {
const container = document.getElementById('modelium-container');
const data = { nodes, edges };
const options = {
manipulation: {
enabled: true,
addNode: false,
addEdge: function (edgeData, callback) {
if (edgeData.from !== edgeData.to) {
const fromNode = nodes.get(edgeData.from);
const toNode = nodes.get(edgeData.to);
if (fromNode.type === 'modelium' && toNode.type === 'model' && toNode.parentId === fromNode.id) {
edgeData.classes = 'modelium-to-model';
}
callback(edgeData);
}
}
},
nodes: {
shape: 'box',
size: 30,
font: { size: 12, color: '#000000' }, // Black text
borderWidth: 2,
shadow: true,
color: {
'modelium': {
background: '#f1c40f',
border: '#f39c12'
},
'model': {
background: '#3498db',
border: '#2980b9'
},
'result': {
background: '#2ecc71',
border: '#27ae60'
},
'return': {
background: '#27ae60',
border: '#1e8449'
}
}
},
edges: {
arrows: {
to: { enabled: true, scaleFactor: 1 },
middle: { enabled: true, scaleFactor: 0.5 }
},
smooth: { type: 'dynamic' },
color: { color: '#848484', highlight: '#848484', hover: '#848484' },
width: 2
},
physics: { enabled: false },
interaction: { hover: true }
};
network = new vis.Network(container, data, options);
network.on("click", function (params) {
if (params.nodes.length > 0) {
showNodeProperties(params.nodes[0]);
} else {
clearProperties();
}
});
setupDragAndDrop();
network.on("edgeAdded", function (params) {
adjustModeliumStructure();
});
network.on("edgeRemoved", function (params) {
adjustModeliumStructure();
});
}
function setupDragAndDrop() {
const container = document.getElementById('modelium-container');
container.ondragover = function (e) { e.preventDefault(); };
container.ondrop = function (e) {
e.preventDefault();
const type = e.dataTransfer.getData("text");
const pos = network.DOMtoCanvas({ x: e.clientX, y: e.clientY });
addNewNode(type, pos.x, pos.y);
};
const nodeTypes = document.getElementsByClassName('node-type');
for (let nodeType of nodeTypes) {
nodeType.ondragstart = function (e) {
e.dataTransfer.setData("text", this.dataset.type);
};
}
}
function addNewNode(type, x, y) {
if (type === 'modelium') {
lastNodeId++;
const modeliumNode = {
id: lastNodeId,
label: 'Modelium',
x: x,
y: y,
type: 'modelium',
group: 'modelium',
chainLength: 1,
loopCount: 0,
parallelCount: 1,
modeliumType: 'standard',
structureDescription: "",
nestedModeliums: []
};
if (modeliumNode.parallelCount > 1) {
modeliumNode.shape = 'box';
modeliumNode.shapeProperties = { borderDashes: [5, 5] };
modeliumNode.icon = {
face: 'FontAwesome',
code: '\uf126',
size: 50,
color: '#000000'
};
}
nodes.add(modeliumNode);
createModeliumStructure(modeliumNode);
} else if (type === 'model') {
lastNodeId++;
let label = 'Model';
if (document.getElementById('show-prompt').checked) label += '\nPrompt: N/A';
if (document.getElementById('show-system-instructions').checked) label += '\nSys Instr: N/A';
if (document.getElementById('show-tools').checked) label += '\nTools: N/A';
if (document.getElementById('show-model-type').checked) label += '\nType: N/A';
const modelNode = {
id: lastNodeId,
label: label,
x: x,
y: y,
type: 'model',
group: 'model',
system_instructions: "",
prompts: "",
model_type: "",
tools: "none"
};
if (modelNode.tools !== 'none') {
modelNode.shape = 'box';
modelNode.shapeProperties = { borderDashes: [5, 5] };
modelNode.icon = {
face: 'FontAwesome',
code: '\uf0ad',
size: 50,
color: '#000000'
};
}
nodes.add(modelNode);
updateModelLabels(modelNode); // Update label after adding model node
} else if (type === 'result') {
lastNodeId++;
const resultNode = {
id: lastNodeId,
label: 'Result',
x: x,
y: y,
type: 'result',
group: 'result'
};
nodes.add(resultNode);
} else if (type === 'return') {
lastNodeId++;
const returnNode = {
id: lastNodeId,
label: 'Return',
x: x,
y: y,
type: 'return',
group: 'return'
};
nodes.add(returnNode);
}
}
function createModeliumStructure(modelium) {
const modelCount = modelium.chainLength * modelium.parallelCount;
const baseX = modelium.x;
const baseY = modelium.y + 100;
let firstModelIds = [];
let lastModelIds = [];
let resultNodeIds = [];
lastNodeId++;
const returnNode = {
id: lastNodeId,
label: 'Return',
type: 'return',
parentId: modelium.id,
x: baseX + (modelium.parallelCount * 150) / 2,
y: baseY + (modelium.chainLength + 1) * 100,
group: 'return'
};
nodes.add(returnNode);
for (let j = 0; j < modelium.parallelCount; j++) {
let lastModelId = modelium.id;
let xOffset = j * 150 - ((modelium.parallelCount - 1) * 75);
for (let i = 0; i < modelium.chainLength; i++) {
lastNodeId++;
const modelNode = {
id: lastNodeId,
label: 'Model',
type: 'model',
parentId: modelium.id,
x: baseX + xOffset,
y: baseY + (i * 100),
group: 'model',
system_instructions: "",
prompts: "",
model_type: "",
tools: "none"
};
if (document.getElementById('show-prompt').checked) modelNode.label += '\nPrompt: ' + (modelNode.prompts || 'N/A');
if (document.getElementById('show-system-instructions').checked) modelNode.label += '\nSys Instr: ' + (modelNode.system_instructions || 'N/A');
if (document.getElementById('show-tools').checked) modelNode.label += '\nTools: ' + (modelNode.tools || 'N/A');
if (document.getElementById('show-model-type').checked) modelNode.label += '\nType: ' + (modelNode.model_type || 'N/A');
if (modelNode.tools !== 'none') {
modelNode.shape = 'box';
modelNode.shapeProperties = { borderDashes: [5, 5] };
modelNode.icon = {
face: 'FontAwesome',
code: '\uf0ad',
size: 50,
color: '#000000'
};
}
nodes.add(modelNode);
if (i === 0) {
edges.add({
from: modelium.id,
to: modelNode.id,
classes: 'modelium-to-model'
});
firstModelIds.push(modelNode.id);
} else {
edges.add({
from: lastModelId,
to: modelNode.id
});
}
lastModelId = modelNode.id;
}
lastNodeId++;
const resultNode = {
id: lastNodeId,
label: 'Result',
type: 'result',
parentId: modelium.id,
x: baseX + xOffset,
y: baseY + (modelium.chainLength * 100),
group: 'result'
};
nodes.add(resultNode);
resultNodeIds.push(resultNode.id);
edges.add({
from: lastModelId,
to: resultNode.id
});
lastModelIds.push(resultNode.id);
}
resultNodeIds.forEach(resultNodeId => {
edges.add({
from: resultNodeId,
to: returnNode.id
});
});
if (modelium.modeliumType === 'chainLoop' && modelium.loopCount > 0) {
lastModelIds.forEach((lastModelId, index) => {
const firstModelId = firstModelIds[index];
edges.add({
id: `loop-${lastModelId}-${firstModelId}`,
from: lastModelId,
to: firstModelId,
smooth: {
type: 'curvedCW',
roundness: 0.3
},
label: `x${modelium.loopCount}`,
font: { size: 10, color: '#848484' },
color: { color: '#848484' },
dashes: [5, 5],
arrows: { to: { enabled: true, scaleFactor: 0.5 } }
});
});
}
modelium.structureDescription = generateStructuredDescription(modelium);
nodes.update(modelium);
}
function generateStructuredDescription(modelium) {
let schema = {
type: modelium.modeliumType,
name: modelium.label, // Include the name of the Modelium
chainLength: modelium.chainLength,
parallelCount: modelium.parallelCount,
loopCount: modelium.loopCount,
models: [],
results: [],
returns: [],
nestedModeliums: []
};
const childNodes = nodes.get({
filter: function (node) {
return node.parentId === modelium.id;
}
});
childNodes.forEach(node => {
switch (node.type) {
case 'model':
schema.models.push({
id: node.id,
systemInstructions: node.system_instructions,
prompts: node.prompts,
modelType: node.model_type,
tools: node.tools
});
break;
case 'result':
schema.results.push({ id: node.id });
break;
case 'return':
schema.returns.push({ id: node.id });
break;
case 'modelium':
// Recursively call generateStructuredDescription for nested Modeliums
schema.nestedModeliums.push(generateStructuredDescription(node));
break;
}
});
return schema;
}
function generateAndDisplayStructuredDescription() {
const modeliumNodes = nodes.get({
filter: function (node) {
return node.type === 'modelium';
}
});
if (modeliumNodes.length === 0) {
alert('No Modelium node found!');
return;
}
const rootModelium = modeliumNodes.reduce((prev, current) =>
(prev.y < current.y) ? prev : current
);
const structuredDescription = generateStructuredDescription(rootModelium);
document.getElementById('structureDescription').value = JSON.stringify(structuredDescription, null, 2);
}
function clearProperties() {
document.getElementById('node-properties').innerHTML = '';
}
function showNodeProperties(nodeId) {
const node = nodes.get(nodeId);
const propertiesDiv = document.getElementById('node-properties');
propertiesDiv.innerHTML = `<h3>${node.label} Properties</h3>`;
if (node.type === 'modelium') {
propertiesDiv.innerHTML += `
<label for="modeliumName">Name:</label><br>
<input type="text" id="modeliumName" value="${node.label}"><br>
<label for="chainLength">Chain Length:</label>
<input type="number" id="chainLength" value="${node.chainLength}" min="1"><br>
<label for="loopCount">Loop Count:</label>
<input type="number" id="loopCount" value="${node.loopCount}" min="0"><br>
<label for="parallelCount">Parallel Count:</label>
<input type="number" id="parallelCount" value="${node.parallelCount}" min="1"><br>
<label for="modeliumType">Modelium Type:</label><br>
<select id="modeliumType">
<option value="standard" ${node.modeliumType === 'standard' ? 'selected' : ''}>Standard</option>
<option value="chainLoop" ${node.modeliumType === 'chainLoop' ? 'selected' : ''}>Chain Loop</option>
<option value="hierarchical" ${node.modeliumType === 'hierarchical' ? 'selected' : ''}>Hierarchical</option>
</select><br>
<button onclick="updateModeliumProperties(${nodeId})">Update Properties</button><br>
<button onclick="generateAndDisplayStructuredDescription(${nodeId})">Generate Structured Description</button><br>
<label for="structureDescription">Structure Description:</label><br>
<textarea id="structureDescription" readonly style="width: 100%; height: 200px;"></textarea><br>
`;
} else if (node.type === 'model') {
propertiesDiv.innerHTML += `
<label for="system_instructions">System Instructions:</label><br>
<textarea id="system_instructions">${node.system_instructions || ''}</textarea><br>
<label for="prompts">Prompts:</label><br>
<textarea id="prompts">${node.prompts || ''}</textarea><br>
<label for="model_type">Model Type:</label><br>
<input type="text" id="model_type" value="${node.model_type || ''}"><br>
<label for="tools">Tools:</label><br>
<select id="tools">
<option value="none" ${node.tools === 'none' ? 'selected' : ''}>None</option>
<option value="all" ${node.tools === 'all' ? 'selected' : ''}>All</option>
<option value="chooser" ${node.tools === 'chooser' ? 'selected' : ''}>Chooser</option>
</select><br>
<button onclick="updateModelProperties(${nodeId})">Update</button>
`;
}
}
function updateModeliumProperties(nodeId) {
const node = nodes.get(nodeId);
node.label = document.getElementById('modeliumName').value;
node.chainLength = parseInt(document.getElementById('chainLength').value);
node.loopCount = parseInt(document.getElementById('loopCount').value);
node.parallelCount = parseInt(document.getElementById('parallelCount').value);
node.modeliumType = document.getElementById('modeliumType').value;
nodes.update(node);
// Remove existing child nodes and edges
const childNodes = nodes.get({
filter: function (node) {
return node.parentId === nodeId;
}
});
nodes.remove(childNodes.map(node => node.id));
edges.remove(edges.getIds({
filter: function (edge) {
return childNodes.some(node => node.id === edge.from || node.id === edge.to);
}
}));
// Recreate the structure based on updated properties
createModeliumStructure(node);
}
function updateModelProperties(nodeId) {
const node = nodes.get(nodeId);
node.system_instructions = document.getElementById('system_instructions').value;
node.prompts = document.getElementById('prompts').value;
node.model_type = document.getElementById('model_type').value;
node.tools = document.getElementById('tools').value;
nodes.update(node);
// Update the label after updating properties
updateModelLabels(node);
}
// Function to adjust the Modelium structure for better visualization
function adjustModeliumStructure() {
// You can implement various logic here based on your visualization needs
// Example:
// 1. Use a layout algorithm (e.g., from vis.js or other libraries)
// 2. Manually reposition nodes based on their connections and depth
// 3. Adjust edge smoothness or curvature for better appearance
// For now, a simple repositioning example:
const allNodes = nodes.get();
let maxX = 0;
allNodes.forEach(node => {
if (node.x > maxX) {
maxX = node.x;
}
});
allNodes.forEach(node => {
node.x = maxX + 100;
nodes.update(node);
});
}
function updateModelLabels(node = null) {
const showPrompt = document.getElementById('show-prompt').checked;
const showSystemInstructions = document.getElementById('show-system-instructions').checked;
const showTools = document.getElementById('show-tools').checked;
const showModelType = document.getElementById('show-model-type').checked;
if (!node) { // If no specific node is passed, update all model nodes
const modelNodes = nodes.get({ filter: n => n.type === 'model' });
modelNodes.forEach(modelNode => {
updateModelLabels(modelNode); // Call recursively to update each model node
});
return;
}
let label = 'Model';
if (showPrompt) label += '\nPrompt: ' + (node.prompts || 'N/A');
if (showSystemInstructions) label += '\nSys Instr: ' + (node.system_instructions || 'N/A');
if (showTools) label += '\nTools: ' + (node.tools || 'N/A');
if (showModelType) label += '\nType: ' + (node.model_type || 'N/A');
node.label = label;
nodes.update(node);
}
initNetwork();
</script>
</body>
</html>
now even more advanced version, but its splited into 3 files:
index.html,
ModeliumDesigner.js
style.css
C:\Users\DELL\Desktop\selfawareGemini\SelAwareAI_Gemini\TESTOWE\visEngine6
├── index.html
├── ModeliumDesigner.js
└── style.css
## File: index.html (in: C:\Users\DELL\Desktop\selfawareGemini\SelAwareAI_Gemini\TESTOWE\visEngine6)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Modelium Designer</title>
<link rel="stylesheet" href="https://unpkg.com/vis-network/styles/vis-network.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css">
<link rel="stylesheet" href="https://unpkg.com/jstree/dist/themes/default/style.min.css" />
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="main-container">
<div id="sidebar">
<button id="showPresetsButton">Show Presets</button>
<div id="sidebar-menu">
<div class="node-type" data-type="modelium" draggable="true">Add Modelium</div>
<div class="node-type" data-type="model" draggable="true">Add Model</div>
<div class="node-type" data-type="result" draggable="true">Add Result</div>
<div class="node-type" data-type="return" draggable="true">Add Return</div>
</div>
<div id="properties">
<h3>Properties</h3>
<div id="node-properties"></div>
</div>
<div>
<input type="checkbox" id="show-prompt" onchange="updateModelLabels()">
<label for="show-prompt">Show Prompt</label>
<input type="checkbox" id="show-system-instructions" onchange="updateModelLabels()">
<label for="show-system-instructions">Show System Instructions</label>
<input type="checkbox" id="show-tools" onchange="updateModelLabels()">
<label for="show-tools">Show Tools</label>
<input type="checkbox" id="show-model-type" onchange="updateModelLabels()">
<label for="show-model-type">Show Model Type</label>
</div>
</div>
<div id="modelium-container"></div>
</div>
<div id="presets-window" class="modal">
<div class="modal-content">
<h2>Presets</h2>
<div id="preset-list"></div>
<button onclick="closePresetsWindow()">Close</button>
</div>
</div>
<div id="prompt-selection-window" class="modal">
<div class="modal-content">
<h2>Select Prompts and Injectors</h2>
<div id="prompt-tree"></div>
<button id="update-prompts-button">Update Prompts</button>
<button onclick="closePromptSelectisonWindow()">Close</button>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
<script src="https://unpkg.com/vis-network/standalone/umd/vis-network.min.js"></script>
<script src="https://unpkg.com/jstree/dist/jstree.min.js"></script>
<script src="ModeliumDesigner.js"></script>
</body>
</html>
## File: ModeliumDesigner.js (in: C:\Users\DELL\Desktop\selfawareGemini\SelAwareAI_Gemini\TESTOWE\visEngine6)
'use strict';
// 1. Data Structures and Initialization
let nodes = new vis.DataSet([]);
let edges = new vis.DataSet([]);
let network = null;
let lastNodeId = 0;
// 2. Presets and Data
const promptsData = [
{
"id": "prompt_root",
"text": "Prompts",
"children": [
{
"id": "sys_general_1",
"text": "General System Prompt 1",
"content": "You are a helpful and harmless AI assistant."
},
{
"id": "prompt_i_1",
"text": "Image Generation Prompt 1",
"content": "Generate an image of a [subject] in the style of [artist]."
}
]
}
];
const presets = {
models: [
{
id: 'gpt-3.5-turbo',
name: 'GPT-3.5 Turbo',
type: 'Generative Language Model',
icon: '🤖',
nickName: "GPT-3.5 Turbo",
prompts: ['sys_general_1'],
system_instructions: "You are a helpful assistant.",
tools: "none",
modelType: "Generative Language Model"
},
{
id: 'dalle-2',
name: 'DALL-E 2',
type: 'Image Generation Model',
icon: '🎨',
nickName: "DALL-E 2",
prompts: ['prompt_i_1'],
system_instructions: "Generate an image based on the given prompt.",
tools: "none",
modelType: "Image Generation Model"
}
],
modeliums: [
{
name: 'Simple Chain',
chainLength: 3,
loopCount: 0,
parallelCount: 1,
modeliumType: 'standard',
structureDescription: "",
nestedModeliums: []
},
{
name: 'Chain with Loop',
chainLength: 2,
loopCount: 3,
parallelCount: 1,
modeliumType: 'chainLoop',
structureDescription: "",
nestedModeliums: []
}
]
};
const modelTypes = [
"Text",
"Image",
"Audio",
"Video",
"Text to Audio",
"Image Generation",
// Add more as needed
];
// 3. Network Initialization
function initNetwork() {
const container = document.getElementById('modelium-container');
const data = { nodes: nodes, edges: edges };
const options = {
manipulation: {
enabled: true,
addNode: false,
addEdge: function (edgeData, callback) {
if (edgeData.from !== edgeData.to) {
const fromNode = nodes.get(edgeData.from);
const toNode = nodes.get(edgeData.to);
if (fromNode.type === 'modelium' && toNode.type === 'model' && toNode.parentId === fromNode.id) {
edgeData.classes = 'modelium-to-model';
}
callback(edgeData);
}
}
},
nodes: {
shape: 'box',
size: 30,
font: { size: 12, color: '#000000' },
borderWidth: 2,
shadow: true,
color: {
'modelium': {
background: '#f1c40f',
border: '#f39c12'
},
'model': {
background: '#3498db',
border: '#2980b9'
},
'result': {
background: '#2ecc71',
border: '#27ae60'
},
'return': {
background: '#27ae60',
border: '#1e8449'
}
}
},
edges: {
arrows: {
to: { enabled: true, scaleFactor: 1 },
middle: { enabled: true, scaleFactor: 0.5 }
},
smooth: { type: 'dynamic' },
color: { color: '#848484', highlight: '#848484', hover: '#848484' },
width: 2
},
physics: { enabled: false },
interaction: { hover: true }
};
network = new vis.Network(container, data, options);
network.on("click", function (params) {
if (params.nodes.length > 0) {
showNodeProperties(params.nodes[0]);
} else {
clearProperties();
}
});
setupDragAndDrop();
network.on("edgeAdded", function (params) {
// You can add logic here if needed when an edge is added
});
network.on("edgeRemoved", function (params) {
// You can add logic here if needed when an edge is removed
});
}
// 4. Drag and Drop Setup
function setupDragAndDrop() {
const container = document.getElementById('modelium-container');
container.ondragover = function (e) {
e.preventDefault();
};
container.ondrop = function (e) {
e.preventDefault();
const type = e.dataTransfer.getData("text");
const pos = network.DOMtoCanvas({ x: e.clientX, y: e.clientY });
addNewNode(type, pos.x, pos.y);
};
const nodeTypes = document.getElementsByClassName('node-type');
for (let nodeType of nodeTypes) {
nodeType.ondragstart = function (e) {
e.dataTransfer.setData("text", this.dataset.type);
};
}
}
// 5. Add New Node
function addNewNode(type, x, y) {
lastNodeId++;
let node = {
id: lastNodeId,
x: x,
y: y,
type: type,
label: type.charAt(0).toUpperCase() + type.slice(1),
chainLength: 1,
loopCount: 0,
parallelCount: 1,
hasInterpreter: true,
model_type: 'Text', // Default model type
tools: 'none' // Default tools setting
};
nodes.add(node);
if (type === 'modelium') {
createModeliumStructure(node);
}
network.fit();
}
// 6. Create Modelium Structure
function createModeliumStructure(modelium) {
const baseX = modelium.x;
const baseY = modelium.y;
const verticalSpacing = 300;
const horizontalSpacing = 500;
const interpreterOffset = 200;
const childNodes = nodes.get({
filter: function (node) {
return node.parentId === modelium.id;
}
});
nodes.remove(childNodes.map(node => node.id));
edges.remove(edges.getIds({
filter: function (edge) {
return childNodes.some(node => node.id === edge.from || node.id === edge.to);
}
}));
for (let p = 0; p < modelium.parallelCount; p++) {
let currentX = baseX + p * horizontalSpacing;
let lastResultId, lastInterpreterResultId;
for (let i = 0; i < modelium.chainLength; i++) {
let currentY = baseY + (i + 1) * verticalSpacing;
lastNodeId++;
const modelNode = {
id: lastNodeId,
label: `Model\nType: Text\nTools: all\nFlags: True\nInterpreter: Yes`,
type: 'model',
parentId: modelium.id,
x: currentX,
y: currentY,
group: 'model'
};
nodes.add(modelNode);
if (i === 0) {
edges.add({
from: modelium.id,
to: modelNode.id,
smooth: { type: 'cubicBezier', roundness: 0.2 }
});
}
lastNodeId++;
const resultNode = {
id: lastNodeId,
label: 'Result',
type: 'result',
parentId: modelium.id,
x: currentX - interpreterOffset / 2,
y: currentY + verticalSpacing / 3,
group: 'result'
};
nodes.add(resultNode);
edges.add({
from: modelNode.id,
to: resultNode.id,
smooth: { type: 'cubicBezier', roundness: 0.2 }
});
lastNodeId++;
const interpreterNode = {
id: lastNodeId,
label: 'Interpreter',
type: 'interpreter',
parentId: modelium.id,
x: currentX + interpreterOffset / 2,
y: currentY + verticalSpacing / 3,
group: 'interpreter'
};
nodes.add(interpreterNode);
lastNodeId++;
const interpreterResultNode = {
id: lastNodeId,
label: 'Interpreter Result',
type: 'result',
parentId: modelium.id,
x: currentX + interpreterOffset / 2,
y: currentY + 2 * (verticalSpacing / 3),
group: 'result'
};
nodes.add(interpreterResultNode);
edges.add({
from: resultNode.id,
to: interpreterNode.id,
smooth: { type: 'cubicBezier', roundness: 0.2 }
});
edges.add({
from: interpreterNode.id,
to: interpreterResultNode.id,
smooth: { type: 'cubicBezier', roundness: 0.2 }
});
if (i < modelium.chainLength - 1) {
edges.add({
from: resultNode.id,
to: lastNodeId + 1,
smooth: { type: 'cubicBezier', roundness: 0.2 }
});
edges.add({
from: interpreterResultNode.id,
to: lastNodeId + 1,
smooth: { type: 'cubicBezier', roundness: 0.2 }
});
} else if (modelium.loopCount > 0 && i === modelium.chainLength - 1) {
const firstModelId = modelNode.id - (modelium.chainLength - 1) * 4;
edges.add({
from: resultNode.id,
to: firstModelId,
smooth: { type: 'cubicBezier', roundness: 0.8 },
dashes: [5, 5],
color: { color: '#ff0000' },
'data-loop-count': modelium.loopCount,
label: modelium.loopCount.toString(), // Display loop count as label
class: 'loop-edge'
});
edges.add({
from: interpreterResultNode.id,
to: firstModelId,
smooth: { type: 'cubicBezier', roundness: 0.8 },
dashes: [5, 5],
color: { color: '#ff0000' },
'data-loop-count': modelium.loopCount,
label: modelium.loopCount.toString(), // Display loop count as label
class: 'loop-edge'
});
}
lastResultId = resultNode.id;
lastInterpreterResultId = interpreterResultNode.id;
}
lastNodeId++;
const returnNode = {
id: lastNodeId,
label: 'Return',
type: 'return',
parentId: modelium.id,
x: currentX,
y: baseY + (modelium.chainLength + 1) * verticalSpacing,
group: 'return'
};
nodes.add(returnNode);
edges.add({
from: lastResultId,
to: returnNode.id,
smooth: { type: 'cubicBezier', roundness: 0.2 }
});
edges.add({
from: lastInterpreterResultId,
to: returnNode.id,
smooth: { type: 'cubicBezier', roundness: 0.2 }
});
}
network.redraw(); // Force Vis.js to redraw
network.fit();
}
// 7. Node Properties Functions
function clearProperties() {
document.getElementById('node-properties').innerHTML = '';
}
function showNodeProperties(nodeId) {
const node = nodes.get(nodeId);
const propertiesDiv = document.getElementById('node-properties');
propertiesDiv.innerHTML = `<h3>${node.label} Properties</h3>`;
if (node.type === 'model') {
propertiesDiv.innerHTML += `
<label for="model_type">Model Type:</label><br>
<select id="model_type">
${modelTypes.map(type => `<option value="${type}" ${node.model_type === type ? 'selected' : ''}>${type}</option>`).join('')}
</select><br>
<label for="system_instructions">System Instructions:</label><br>
<textarea id="system_instructions">${node.system_instructions || ''}</textarea><br>
<label for="prompts">Prompts:</label><br>
<button id="select-prompts-button" onclick="openPromptSelectionWindow(${nodeId})">Select Prompts</button><br>
<label for="tools">Tools:</label><br>
<select id="tools">
<option value="none" ${node.tools === 'none' ? 'selected' : ''}>None</option>
<option value="all" ${node.tools === 'all' ? 'selected' : ''}>All</option>
<option value="chooser" ${node.tools === 'chooser' ? 'selected' : ''}>Chooser</option>
</select><br>
<label for="flags">Flags:</label><br>
<input type="checkbox" id="flags" ${node.flags ? 'checked' : ''}><br>
<label for="has_interpreter">Has Interpreter:</label><br>
<input type="checkbox" id="has_interpreter" ${node.has_interpreter ? 'checked' : ''}><br>
<button onclick="updateModelProperties(${nodeId})">Update</button>
`;
} else if (node.type === 'modelium') {
propertiesDiv.innerHTML += `
<label for="modeliumName">Name:</label><br>
<input type="text" id="modeliumName" value="${node.label}"><br>
<label for="chainLength">Chain Length:</label><br>
<input type="number" id="chainLength" value="${node.chainLength}"><br>
<label for="loopCount">Loop Count:</label><br>
<input type="number" id="loopCount" value="${node.loopCount}"><br>
<label for="parallelCount">Parallel Count:</label><br>
<input type="number" id="parallelCount" value="${node.parallelCount}"><br>
<label for="modeliumType">Modelium Type:</label><br>
<select id="modeliumType">
<option value="standard" ${node.modeliumType === 'standard' ? 'selected' : ''}>Standard</option>
<option value="chainLoop" ${node.modeliumType === 'chainLoop' ? 'selected' : ''}>Chain Loop</option>
</select><br>
<button onclick="updateModeliumProperties(${nodeId})">Update</button>
`;
}
}
// 8. Update Node Properties Functions
function updateModeliumProperties(nodeId) {
const node = nodes.get(nodeId);
node.label = document.getElementById('modeliumName').value;
node.chainLength = parseInt(document.getElementById('chainLength').value);
node.loopCount = parseInt(document.getElementById('loopCount').value);
node.parallelCount = parseInt(document.getElementById('parallelCount').value);
node.modeliumType = document.getElementById('modeliumType').value;
nodes.update(node);
const childNodes = nodes.get({
filter: function (node) {
return node.parentId === nodeId;
}
});
nodes.remove(childNodes.map(node => node.id));
edges.remove(edges.getIds({
filter: function (edge) {
return childNodes.some(node => node.id === edge.from || node.id === edge.to);
}
}));
createModeliumStructure(node);
}
function updateModelProperties(nodeId) {
const node = nodes.get(nodeId);
node.model_type = document.getElementById('model_type').value;
node.system_instructions = document.getElementById('system_instructions').value;
node.tools = document.getElementById('tools').value;
node.flags = document.getElementById('flags').checked;
const hasInterpreter = document.getElementById('has_interpreter').checked;
if (hasInterpreter && !node.has_interpreter) {
addInterpreterNode(node);
node.has_interpreter = true;
} else if (!hasInterpreter && node.has_interpreter) {
removeInterpreterNode(node);
node.has_interpreter = false;
}
nodes.update(node);
updateModelLabels(node);
}
// 9. Interpreter Node Management
function removeInterpreterNode(modelNode) {
const connectedEdges = network.getConnectedEdges(modelNode.id);
const interpreterEdge = edges.get(connectedEdges.find(edgeId => {
const edge = edges.get(edgeId);
return edge.from === modelNode.id && nodes.get(edge.to).type === 'interpreter';
}));
if (interpreterEdge) {
const interpreterNode = nodes.get(interpreterEdge.to);
const interpreterResultEdge = edges.get(network.getConnectedEdges(interpreterNode.id).find(edgeId => {
const edge = edges.get(edgeId);
return edge.from === interpreterNode.id && nodes.get(edge.to).type === 'result';
}));
if (interpreterResultEdge) {
nodes.remove(interpreterResultEdge.to);
edges.remove(interpreterResultEdge.id);
}
nodes.remove(interpreterNode.id);
edges.remove(interpreterEdge.id);
}
}
function addInterpreterNode(modelNode) {
lastNodeId++;
const interpreterNode = {
id: lastNodeId,
label: 'Interpreter',
type: 'interpreter',
group: 'interpreter',
x: modelNode.x + 100,
y: modelNode.y + 50
};
nodes.add(interpreterNode);
edges.add({from: modelNode.id, to: interpreterNode.id});
lastNodeId++;
const interpreterResultNode = {
id: lastNodeId,
label: 'Interpreter Result',
type: 'result',
group: 'result',
x: interpreterNode.x + 50,
y: interpreterNode.y + 50
};
nodes.add(interpreterResultNode);
edges.add({from: interpreterNode.id, to: interpreterResultNode.id});
}
// 10. Update Model Labels
function updateModelLabels(node = null) {
const showModelType = document.getElementById('show-model-type')?.checked || false;
const showTools = document.getElementById('show-tools')?.checked || false;
if (!node) {
const modelNodes = nodes.get({ filter: n => n.type === 'model' });
modelNodes.forEach(modelNode => {
updateModelLabels(modelNode);
});
return;
}
let label = 'Model';
if (showModelType) label += '\nType: ' + (node.model_type || 'N/A');
if (showTools) label += '\nTools: ' + (node.tools || 'N/A');
label += '\nFlags: ' + (node.flags ? 'True' : 'False');
label += '\nInterpreter: ' + (node.has_interpreter ? 'Yes' : 'No');
node.label = label;
nodes.update(node);
}
// 11. Prompt Selection Window
function openPromptSelectionWindow(nodeId) {
const promptSelectionWindow = document.getElementById('prompt-selection-window');
promptSelectionWindow.style.display = 'block';
$('#prompt-tree').jstree({
'core': {
'data': promptsData
}
});
promptSelectionWindow.dataset.nodeId = nodeId;
}
function closePromptSelectisonWindow() {
const promptSelectionWindow = document.getElementById('prompt-selection-window');
promptSelectionWindow.style.display = 'none';
}
function updatePromptsForModel(nodeId) {
const modelNode = nodes.get(nodeId);
const selectedPrompts = $('#prompt-tree').jstree('get_selected');
modelNode.prompts = selectedPrompts;
nodes.update(modelNode);
updateModelLabels(modelNode);
}
// 13. Event Listeners
document.addEventListener('DOMContentLoaded', function () {
initNetwork();
});
document.getElementById('update-prompts-button').addEventListener('click', function() {
const promptSelectionWindow = document.getElementById('prompt-selection-window');
const nodeId = promptSelectionWindow.dataset.nodeId;
updatePromptsForModel(nodeId);
closePromptSelectisonWindow();
});
## File: style.css (in: C:\Users\DELL\Desktop\selfawareGemini\SelAwareAI_Gemini\TESTOWE\visEngine6)
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
margin: 0;
padding: 0;
display: flex;
height: 100vh;
background-color: #181818;
color: #eee;
}
.main-container {
display: flex;
height: 100%;
}
#modelium-container {
flex-grow: 1;
border: 1px solid #333;
background-color: #282828;
}
#sidebar {
width: 300px;
background-color: #282828;
padding: 20px;
overflow-y: auto;
display: flex;
flex-direction: column;
box-shadow: -2px 0 5px rgba(0, 0, 0, 0.2);
}
#sidebar-menu {
flex-grow: 1;
padding-bottom: 20px;
}
.node-type {
padding: 10px;
border: 1px solid #333;
margin-bottom: 5px;
cursor: pointer;
background-color: #333;
border-radius: 5px;
transition: background-color 0.2s ease;
}
.node-type:hover {
background-color: #444;
}
#properties {
margin-top: 20px;
}
#node-properties h3 {
margin-top: 0;
color: #eee;
font-weight: bold;
}
#node-properties label {
display: block;
margin-bottom: 5px;
color: #eee;
}
#node-properties input,
#node-properties textarea,
#node-properties select {
width: 100%;
padding: 8px;
margin-bottom: 10px;
border: 1px solid #555;
border-radius: 5px;
background-color: #222;
color: #eee;
}
.modelium-to-model {
color: #f39c12;
width: 3px;
}
.modelium-to-model .vis-edge .vis-line {
stroke-dasharray: 5, 5;
}
#sidebar button,
.modal-content button {
padding: 8px 15px;
background-color: #3498db;
color: white;
border: none;
cursor: pointer;
border-radius: 5px;
margin-bottom: 10px;
transition: background-color 0.2s ease;
}
#sidebar button:hover,
.modal-content button:hover {
background-color: #2980b9;
}
.node-icon {
position: absolute;
top: -10px;
right: -10px;
width: 20px;
height: 20px;
background-size: cover;
}
.tools-icon {
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAjklEQVR4nO3UQQqDMBCF4X+yCXgQ7yEIgu4KvULXbQW9/26KCSWSlEKpC1cDswj5mMwbQoxxwWtaawvr7+xYa21pCYEHjtivtTiDz5RSqfSctR0X5JzPD+NKqTp0xLRjWlzQe7+WUnZCiA0ppQ0hxK6UsvfeX//6XT/ihjue0Fq71VrXEMKhtfZijLl9Mz8BmI0StacvT10AAAAASUVORK5CYII=');
}
.parallel-icon {
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAV0lEQVR4nGNgGAWjYKiD/wDMQKwCZD4TsS4k1jByDWMiRhGxLiTFMCZiFRHrQlINYyJGEbEuJMcwJkIKiXUhuYYx4VNIiovINYyJkEJiXUiJYaNgZAMAYnAb1CJ5IcEAAAAASUVORK5CYII=');
}
.vis-node {
border-width: 2px;
box-shadow: 0 0 10px rgba(0,0,0,0.5);
padding: 10px;
}
.vis-node.modelium {
background-color: #f1c40f;
border-color: #f39c12;
}
.vis-node.model {
background-color: #3498db;
border-color: #2980b9;
}
.vis-node.result {
background-color: #2ecc71;
border-color: #27ae60;
}
.vis-node.return {
background-color: #27ae60;
border-color: #1e8449;
}
.vis-node .vis-label {
color: #000;
font-size: 12px;
}
.vis-node.model.with-tools {
min-height: 100px;
}
.vis-node.model.with-loop {
min-height: 120px;
}
.modal {
display: none;
position: fixed;
z-index: 1;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgb(0,0,0);
background-color: rgba(0,0,0,0.4);
}
.modal-content {
background-color: #fefefe;
margin: 15% auto;
padding: 20px;
border: 1px solid #888;
width: 80%;
}