Add files via upload
This commit is contained in:
parent
f22107daf1
commit
969e1ed7ed
7 changed files with 6449 additions and 0 deletions
21
LLM Desktop Chatbot Apps/ThinkPath-Chatbot-App/LICENSE
Normal file
21
LLM Desktop Chatbot Apps/ThinkPath-Chatbot-App/LICENSE
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2025 Ahmed El-Taher
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
Binary file not shown.
884
LLM Desktop Chatbot Apps/ThinkPath-Chatbot-App/index.html
Normal file
884
LLM Desktop Chatbot Apps/ThinkPath-Chatbot-App/index.html
Normal file
|
|
@ -0,0 +1,884 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Guided LLM Chat</title>
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||||
height: 100vh;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.title-bar {
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
height: 40px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 15px;
|
||||
color: white;
|
||||
font-size: 14px;
|
||||
-webkit-app-region: drag;
|
||||
}
|
||||
|
||||
.title-text {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.window-controls {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
-webkit-app-region: no-drag;
|
||||
}
|
||||
|
||||
.window-btn {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border-radius: 50%;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.window-btn:hover {
|
||||
transform: scale(1.2);
|
||||
}
|
||||
|
||||
.btn-close {
|
||||
background: #ff5f57;
|
||||
}
|
||||
|
||||
.btn-close:hover {
|
||||
background: #ff3b30;
|
||||
}
|
||||
|
||||
.btn-minimize {
|
||||
background: #ffbd2e;
|
||||
}
|
||||
|
||||
.btn-minimize:hover {
|
||||
background: #ff9500;
|
||||
}
|
||||
|
||||
.btn-maximize {
|
||||
background: #28ca42;
|
||||
}
|
||||
|
||||
.btn-maximize:hover {
|
||||
background: #30d158;
|
||||
}
|
||||
|
||||
.update-paths-btn {
|
||||
background: #6c757d;
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 8px 16px;
|
||||
border-radius: 15px;
|
||||
cursor: pointer;
|
||||
font-size: 12px;
|
||||
margin-bottom: 15px;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.update-paths-btn:hover {
|
||||
background: #5a6268;
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.update-paths-btn:disabled {
|
||||
background: #ccc;
|
||||
cursor: not-allowed;
|
||||
transform: none;
|
||||
}
|
||||
|
||||
.chat-container {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
max-width: 1000px;
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.chat-messages {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
padding: 20px;
|
||||
background: rgba(255, 255, 255, 0.95);
|
||||
border-radius: 15px 15px 0 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.message {
|
||||
margin-bottom: 20px;
|
||||
padding: 15px;
|
||||
border-radius: 12px;
|
||||
max-width: 80%;
|
||||
animation: fadeIn 0.3s ease-in;
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from { opacity: 0; transform: translateY(10px); }
|
||||
to { opacity: 1; transform: translateY(0); }
|
||||
}
|
||||
|
||||
.user-message {
|
||||
background: #007bff;
|
||||
color: white;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.bot-message {
|
||||
background: #f8f9fa;
|
||||
color: #333;
|
||||
border: 1px solid #e9ecef;
|
||||
}
|
||||
|
||||
.loading {
|
||||
background: #f8f9fa;
|
||||
color: #666;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.thinking-paths {
|
||||
background: rgba(255, 255, 255, 0.95);
|
||||
padding: 20px;
|
||||
border-radius: 0 0 15px 15px;
|
||||
border-top: 1px solid #e9ecef;
|
||||
}
|
||||
|
||||
.paths-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
|
||||
gap: 15px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.thinking-path {
|
||||
background: #f8f9fa;
|
||||
border: 1px solid #e9ecef;
|
||||
border-radius: 12px;
|
||||
padding: 15px;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.thinking-path:hover {
|
||||
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.path-header {
|
||||
font-weight: 600;
|
||||
font-size: 14px;
|
||||
color: #495057;
|
||||
margin-bottom: 12px;
|
||||
text-align: center;
|
||||
padding-bottom: 8px;
|
||||
border-bottom: 1px solid #dee2e6;
|
||||
}
|
||||
|
||||
.path-steps {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.path-step {
|
||||
padding: 8px 12px;
|
||||
margin: 6px 0;
|
||||
border-radius: 8px;
|
||||
font-size: 13px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
border: 1px solid transparent;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.path-step:hover {
|
||||
background: #e9ecef;
|
||||
border-color: #c8b99c;
|
||||
}
|
||||
|
||||
.path-step:before {
|
||||
content: attr(data-step);
|
||||
background: #c8b99c;
|
||||
color: white;
|
||||
border-radius: 50%;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 11px;
|
||||
font-weight: bold;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.thinking-indicator {
|
||||
text-align: center;
|
||||
padding: 20px;
|
||||
color: #666;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.response-with-path {
|
||||
background: #e8f4f8;
|
||||
border-left: 4px solid #17a2b8;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.path-info {
|
||||
font-size: 12px;
|
||||
color: #17a2b8;
|
||||
font-weight: 600;
|
||||
margin-bottom: 12px;
|
||||
padding: 8px 12px;
|
||||
background: rgba(23, 162, 184, 0.1);
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.response-content {
|
||||
line-height: 1.7;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.response-content strong,
|
||||
.response-content b {
|
||||
color: #2c3e50;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.response-content h3 {
|
||||
color: #2c3e50;
|
||||
font-size: 16px;
|
||||
margin: 15px 0 10px 0;
|
||||
padding-bottom: 6px;
|
||||
border-bottom: 2px solid #3498db;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.response-content h4 {
|
||||
color: #34495e;
|
||||
font-size: 15px;
|
||||
margin: 14px 0 8px 0;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.response-content p {
|
||||
margin: 10px 0;
|
||||
color: #2c3e50;
|
||||
}
|
||||
|
||||
.response-content ul {
|
||||
margin: 8px 0 12px 20px;
|
||||
color: #2c3e50;
|
||||
}
|
||||
|
||||
.response-content li {
|
||||
margin: 4px 0;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.thinking-step {
|
||||
background: #f8f9fa;
|
||||
border-left: 4px solid #17a2b8;
|
||||
padding: 15px 18px;
|
||||
margin: 12px 0;
|
||||
border-radius: 0 8px 8px 0;
|
||||
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
.thinking-step h4 {
|
||||
color: #17a2b8 !important;
|
||||
margin-top: 0 !important;
|
||||
margin-bottom: 10px !important;
|
||||
font-size: 15px !important;
|
||||
font-weight: 600 !important;
|
||||
}
|
||||
|
||||
.auto-updating {
|
||||
background: #fff3cd;
|
||||
border: 1px solid #ffeaa7;
|
||||
padding: 8px 12px;
|
||||
border-radius: 6px;
|
||||
font-size: 12px;
|
||||
color: #856404;
|
||||
margin-bottom: 10px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.step-executed {
|
||||
background: #d4edda !important;
|
||||
border-color: #c3e6cb !important;
|
||||
}
|
||||
|
||||
.step-executed:before {
|
||||
background: #28a745 !important;
|
||||
}
|
||||
|
||||
.input-container {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
.chat-input {
|
||||
flex: 1;
|
||||
padding: 12px 16px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 25px;
|
||||
font-size: 16px;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.chat-input:focus {
|
||||
border-color: #007bff;
|
||||
box-shadow: 0 0 0 3px rgba(0,123,255,0.1);
|
||||
}
|
||||
|
||||
.send-btn {
|
||||
background: #007bff;
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 12px 20px;
|
||||
border-radius: 25px;
|
||||
cursor: pointer;
|
||||
font-size: 16px;
|
||||
transition: background 0.2s ease;
|
||||
}
|
||||
|
||||
.send-btn:hover {
|
||||
background: #0056b3;
|
||||
}
|
||||
|
||||
.send-btn:disabled {
|
||||
background: #ccc;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.category-label {
|
||||
font-size: 12px;
|
||||
color: #666;
|
||||
margin-bottom: 8px;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
|
||||
.actions-section {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.status-indicator {
|
||||
position: fixed;
|
||||
top: 40px;
|
||||
right: 20px;
|
||||
padding: 8px 16px;
|
||||
border-radius: 20px;
|
||||
font-size: 12px;
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
border: 1px solid #ddd;
|
||||
}
|
||||
|
||||
.status-connected {
|
||||
color: #28a745;
|
||||
}
|
||||
|
||||
.status-disconnected {
|
||||
color: #dc3545;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="title-bar">
|
||||
<div class="window-controls">
|
||||
<button class="window-btn btn-close" onclick="closeWindow()" title="Close"></button>
|
||||
<button class="window-btn btn-minimize" onclick="minimizeWindow()" title="Minimize"></button>
|
||||
<button class="window-btn btn-maximize" onclick="toggleMaximize()" title="Maximize"></button>
|
||||
</div>
|
||||
<div class="title-text">
|
||||
Guided LLM Chat - Strategic Thinking Assistant
|
||||
</div>
|
||||
<div style="width: 70px;"></div> <!-- Spacer for centering -->
|
||||
</div>
|
||||
|
||||
<div class="status-indicator" id="status">
|
||||
<span class="status-disconnected">● Connecting...</span>
|
||||
</div>
|
||||
|
||||
<div class="chat-container">
|
||||
<div class="chat-messages" id="chatMessages">
|
||||
<div class="message bot-message">
|
||||
🧠 Hello! I'm your strategic thinking assistant. Ask me any question and I'll generate different thinking approaches for you to explore step-by-step. Each approach offers a unique way to tackle your problem.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="thinking-paths" id="thinkingPaths">
|
||||
<div class="thinking-indicator">
|
||||
Ask me a question and I'll show you different thinking approaches...
|
||||
</div>
|
||||
|
||||
<div class="input-container">
|
||||
<input type="text" class="chat-input" id="chatInput" placeholder="Type your question..." onkeypress="handleKeyPress(event)">
|
||||
<button class="send-btn" id="sendBtn" onclick="sendMessage()">Send</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const { ipcRenderer } = require('electron');
|
||||
|
||||
let isConnected = false;
|
||||
let isLoading = false;
|
||||
|
||||
// Check Ollama connection on startup
|
||||
checkOllamaConnection();
|
||||
|
||||
async function checkOllamaConnection() {
|
||||
try {
|
||||
const result = await ipcRenderer.invoke('send-to-llm', 'test');
|
||||
isConnected = result.success;
|
||||
updateStatus();
|
||||
} catch (error) {
|
||||
isConnected = false;
|
||||
updateStatus();
|
||||
}
|
||||
}
|
||||
|
||||
function updateStatus() {
|
||||
const statusEl = document.getElementById('status');
|
||||
if (isConnected) {
|
||||
statusEl.innerHTML = '<span class="status-connected">● Connected to Llama</span>';
|
||||
} else {
|
||||
statusEl.innerHTML = '<span class="status-disconnected">● Disconnected</span>';
|
||||
}
|
||||
}
|
||||
|
||||
function addMessage(content, isUser = false, isLoading = false) {
|
||||
const messagesContainer = document.getElementById('chatMessages');
|
||||
const messageEl = document.createElement('div');
|
||||
|
||||
let className = 'message ';
|
||||
if (isUser) className += 'user-message';
|
||||
else if (isLoading) className += 'loading';
|
||||
else className += 'bot-message';
|
||||
|
||||
messageEl.className = className;
|
||||
messageEl.textContent = content;
|
||||
|
||||
messagesContainer.appendChild(messageEl);
|
||||
messagesContainer.scrollTop = messagesContainer.scrollHeight;
|
||||
|
||||
return messageEl;
|
||||
}
|
||||
|
||||
let currentQuery = '';
|
||||
let currentPaths = [];
|
||||
let conversationContext = [];
|
||||
let lastBotResponse = '';
|
||||
|
||||
// Window control functions
|
||||
async function closeWindow() {
|
||||
await ipcRenderer.invoke('window-close');
|
||||
}
|
||||
|
||||
async function minimizeWindow() {
|
||||
await ipcRenderer.invoke('window-minimize');
|
||||
}
|
||||
|
||||
async function toggleMaximize() {
|
||||
await ipcRenderer.invoke('window-maximize');
|
||||
}
|
||||
|
||||
async function sendMessage() {
|
||||
if (isLoading) return;
|
||||
|
||||
const input = document.getElementById('chatInput');
|
||||
const message = input.value.trim();
|
||||
|
||||
if (!message) return;
|
||||
|
||||
// Store current query
|
||||
currentQuery = message;
|
||||
|
||||
// Add user message
|
||||
addMessage(message, true);
|
||||
input.value = '';
|
||||
|
||||
// Show thinking indicator
|
||||
isLoading = true;
|
||||
document.getElementById('sendBtn').disabled = true;
|
||||
showThinkingIndicator('Analyzing your question and generating thinking approaches...');
|
||||
|
||||
try {
|
||||
// Generate thinking paths
|
||||
const pathsResult = await ipcRenderer.invoke('generate-thinking-paths', message);
|
||||
|
||||
if (pathsResult.success && pathsResult.paths.length > 0) {
|
||||
currentPaths = pathsResult.paths;
|
||||
displayThinkingPaths(pathsResult.paths, false); // First time, no update button
|
||||
isConnected = true;
|
||||
} else {
|
||||
addMessage(`Error generating thinking paths: ${pathsResult.error || 'Unknown error'}`, false);
|
||||
hideThinkingPaths();
|
||||
isConnected = false;
|
||||
}
|
||||
} catch (error) {
|
||||
addMessage(`Connection error: ${error.message}`, false);
|
||||
hideThinkingPaths();
|
||||
isConnected = false;
|
||||
}
|
||||
|
||||
isLoading = false;
|
||||
document.getElementById('sendBtn').disabled = false;
|
||||
updateStatus();
|
||||
}
|
||||
|
||||
function showThinkingIndicator(message) {
|
||||
const thinkingPathsEl = document.getElementById('thinkingPaths');
|
||||
thinkingPathsEl.innerHTML = `
|
||||
<div class="thinking-indicator">${message}</div>
|
||||
<div class="input-container">
|
||||
<input type="text" class="chat-input" id="chatInput" placeholder="Type your question..." onkeypress="handleKeyPress(event)">
|
||||
<button class="send-btn" id="sendBtn" onclick="sendMessage()">Send</button>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
function displayThinkingPaths(paths, showUpdateButton = false, isAutoUpdate = false) {
|
||||
const thinkingPathsEl = document.getElementById('thinkingPaths');
|
||||
|
||||
let pathsHTML = `
|
||||
<div class="thinking-indicator">Choose a thinking approach and step:</div>
|
||||
`;
|
||||
|
||||
// Show auto-update indicator if this was automatically generated
|
||||
if (isAutoUpdate) {
|
||||
pathsHTML += `
|
||||
<div class="auto-updating">
|
||||
🔄 Approaches automatically updated based on conversation
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
// Add manual update button if there's conversation context
|
||||
if (showUpdateButton) {
|
||||
pathsHTML += `
|
||||
<button class="update-paths-btn" id="updatePathsBtn" onclick="updateThinkingPaths()">
|
||||
🔄 Generate New Approaches Based on Conversation
|
||||
</button>
|
||||
`;
|
||||
}
|
||||
|
||||
pathsHTML += '<div class="paths-grid">';
|
||||
|
||||
paths.forEach((path, pathIndex) => {
|
||||
pathsHTML += `
|
||||
<div class="thinking-path">
|
||||
<div class="path-header">${path.name}</div>
|
||||
<ul class="path-steps">
|
||||
`;
|
||||
|
||||
path.steps.forEach((step, stepIndex) => {
|
||||
pathsHTML += `
|
||||
<li class="path-step"
|
||||
data-step="${stepIndex + 1}"
|
||||
onclick="executeThinkingPath(${pathIndex}, ${stepIndex + 1})">
|
||||
${step}
|
||||
</li>
|
||||
`;
|
||||
});
|
||||
|
||||
pathsHTML += '</ul></div>';
|
||||
});
|
||||
|
||||
pathsHTML += `
|
||||
</div>
|
||||
<div class="input-container">
|
||||
<input type="text" class="chat-input" id="chatInput" placeholder="Type your question..." onkeypress="handleKeyPress(event)">
|
||||
<button class="send-btn" id="sendBtn" onclick="sendMessage()">Send</button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
thinkingPathsEl.innerHTML = pathsHTML;
|
||||
}
|
||||
|
||||
async function autoUpdateThinkingPaths(pathName, stepsExecuted) {
|
||||
try {
|
||||
const pathsResult = await ipcRenderer.invoke('generate-updated-paths', {
|
||||
originalQuery: currentQuery,
|
||||
lastResponse: lastBotResponse,
|
||||
conversationContext: conversationContext,
|
||||
lastPathName: pathName,
|
||||
lastStepsExecuted: stepsExecuted
|
||||
});
|
||||
|
||||
if (pathsResult.success && pathsResult.paths.length > 0) {
|
||||
currentPaths = pathsResult.paths;
|
||||
displayThinkingPaths(pathsResult.paths, true, true); // Show as auto-updated
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error auto-updating paths:', error);
|
||||
}
|
||||
}
|
||||
|
||||
async function executeThinkingPath(pathIndex, stepNumber) {
|
||||
if (isLoading) return;
|
||||
|
||||
const path = currentPaths[pathIndex];
|
||||
if (!path) return;
|
||||
|
||||
// Show loading
|
||||
isLoading = true;
|
||||
document.getElementById('sendBtn').disabled = true;
|
||||
|
||||
// Highlight executed steps
|
||||
highlightExecutedSteps(pathIndex, stepNumber);
|
||||
|
||||
const loadingEl = addMessage(`Following "${path.name}" approach through step ${stepNumber}...`, false, true);
|
||||
|
||||
try {
|
||||
const result = await ipcRenderer.invoke('execute-thinking-path', {
|
||||
query: currentQuery,
|
||||
pathName: path.name,
|
||||
steps: path.steps,
|
||||
executeUpToStep: stepNumber
|
||||
});
|
||||
|
||||
// Remove loading message
|
||||
loadingEl.remove();
|
||||
|
||||
if (result.success) {
|
||||
// Store the response for context
|
||||
lastBotResponse = result.response;
|
||||
conversationContext.push({
|
||||
query: currentQuery,
|
||||
pathName: result.pathName,
|
||||
stepsExecuted: result.stepsExecuted,
|
||||
response: result.response
|
||||
});
|
||||
|
||||
// Add response with path info
|
||||
addMessageWithPath(result.response, result.pathName, result.stepsExecuted);
|
||||
|
||||
// Auto-generate new thinking paths based on the response
|
||||
setTimeout(() => {
|
||||
autoUpdateThinkingPaths(result.pathName, result.stepsExecuted);
|
||||
}, 1000); // Small delay for better UX
|
||||
|
||||
isConnected = true;
|
||||
} else {
|
||||
addMessage(`Error: ${result.error}`, false);
|
||||
isConnected = false;
|
||||
}
|
||||
} catch (error) {
|
||||
loadingEl.remove();
|
||||
addMessage(`Connection error: ${error.message}`, false);
|
||||
isConnected = false;
|
||||
}
|
||||
|
||||
isLoading = false;
|
||||
document.getElementById('sendBtn').disabled = false;
|
||||
updateStatus();
|
||||
}
|
||||
|
||||
function highlightExecutedSteps(pathIndex, stepNumber) {
|
||||
// Reset all steps
|
||||
document.querySelectorAll('.path-step').forEach(step => {
|
||||
step.classList.remove('step-executed');
|
||||
});
|
||||
|
||||
// Highlight executed steps in the selected path
|
||||
const pathElement = document.querySelectorAll('.thinking-path')[pathIndex];
|
||||
const steps = pathElement.querySelectorAll('.path-step');
|
||||
|
||||
for (let i = 0; i < stepNumber; i++) {
|
||||
if (steps[i]) {
|
||||
steps[i].classList.add('step-executed');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function addMessageWithPath(content, pathName, stepsExecuted) {
|
||||
const messagesContainer = document.getElementById('chatMessages');
|
||||
const messageEl = document.createElement('div');
|
||||
|
||||
// Format the response content to highlight thinking steps
|
||||
const formattedContent = formatThinkingResponse(content);
|
||||
|
||||
messageEl.className = 'message bot-message response-with-path';
|
||||
messageEl.innerHTML = `
|
||||
<div class="path-info">
|
||||
🧠 Following "${pathName}" approach - Steps 1-${stepsExecuted} executed
|
||||
</div>
|
||||
<div class="response-content">${formattedContent}</div>
|
||||
`;
|
||||
|
||||
messagesContainer.appendChild(messageEl);
|
||||
messagesContainer.scrollTop = messagesContainer.scrollHeight;
|
||||
|
||||
return messageEl;
|
||||
}
|
||||
|
||||
function formatThinkingResponse(content) {
|
||||
// Convert the response to show clear thinking steps with better formatting
|
||||
let formatted = content;
|
||||
|
||||
// Format step headers (e.g., "Step 1:", "**Step 1:**", etc.)
|
||||
formatted = formatted.replace(/\*\*Step (\d+):(.*?)\*\*/g, '<div class="thinking-step"><h4>🔹 Step $1:$2</h4>');
|
||||
formatted = formatted.replace(/Step (\d+):(.*?)(?=\n|Step|\*\*|$)/g, '<div class="thinking-step"><h4>🔹 Step $1:$2</h4>');
|
||||
|
||||
// Format bold text (**text**)
|
||||
formatted = formatted.replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>');
|
||||
|
||||
// Format bullet points (• or *)
|
||||
formatted = formatted.replace(/^[•*]\s+(.+)$/gm, '<li>$1</li>');
|
||||
formatted = formatted.replace(/(<li>.*<\/li>)/gs, '<ul>$1</ul>');
|
||||
|
||||
// Clean up multiple consecutive ul tags
|
||||
formatted = formatted.replace(/<\/ul>\s*<ul>/g, '');
|
||||
|
||||
// Format numbered lists (1. 2. 3.)
|
||||
formatted = formatted.replace(/^(\d+)\.\s+(.+)$/gm, '<li>$2</li>');
|
||||
|
||||
// Close thinking step divs (simple approach - close before next step or at summary)
|
||||
formatted = formatted.replace(/(<div class="thinking-step">.*?)<div class="thinking-step">/gs, '$1</div><div class="thinking-step">');
|
||||
|
||||
// Handle summary section
|
||||
formatted = formatted.replace(/\*\*Summary:\*\*/g, '</div><h3>📋 Summary:</h3>');
|
||||
formatted = formatted.replace(/Summary:/g, '</div><h3>📋 Summary:</h3>');
|
||||
|
||||
// Handle approach headers
|
||||
formatted = formatted.replace(/\*\*Following "(.*?)" Approach:\*\*/g, '<h3>🎯 Following "$1" Approach:</h3>');
|
||||
|
||||
// Format scenario headers (like "Optimistic Scenario", "Moderate Scenario", etc.)
|
||||
formatted = formatted.replace(/\*\*([A-Z][a-z]+ Scenario[^*]*)\*\*/g, '<h4><strong>$1</strong></h4>');
|
||||
|
||||
// Format any remaining bold patterns
|
||||
formatted = formatted.replace(/\*([^*]+)\*/g, '<em>$1</em>');
|
||||
|
||||
// Close any remaining open thinking-step divs
|
||||
if (formatted.includes('<div class="thinking-step">') && !formatted.endsWith('</div>')) {
|
||||
formatted += '</div>';
|
||||
}
|
||||
|
||||
// Convert line breaks to proper HTML
|
||||
formatted = formatted.replace(/\n\n/g, '</p><p>');
|
||||
formatted = formatted.replace(/\n/g, '<br>');
|
||||
|
||||
// Wrap in paragraphs where needed
|
||||
if (!formatted.includes('<p>') && !formatted.includes('<div>') && !formatted.includes('<h3>')) {
|
||||
formatted = '<p>' + formatted + '</p>';
|
||||
}
|
||||
|
||||
return formatted;
|
||||
}
|
||||
|
||||
async function updateThinkingPaths() {
|
||||
if (isLoading) return;
|
||||
|
||||
isLoading = true;
|
||||
document.getElementById('updatePathsBtn').disabled = true;
|
||||
document.getElementById('updatePathsBtn').textContent = '🔄 Generating...';
|
||||
|
||||
try {
|
||||
const pathsResult = await ipcRenderer.invoke('generate-updated-paths', {
|
||||
originalQuery: currentQuery,
|
||||
lastResponse: lastBotResponse,
|
||||
conversationContext: conversationContext,
|
||||
lastPathName: conversationContext[conversationContext.length - 1]?.pathName || '',
|
||||
lastStepsExecuted: conversationContext[conversationContext.length - 1]?.stepsExecuted || 1
|
||||
});
|
||||
|
||||
if (pathsResult.success && pathsResult.paths.length > 0) {
|
||||
currentPaths = pathsResult.paths;
|
||||
displayThinkingPaths(pathsResult.paths, true, false); // Manual update, not auto
|
||||
} else {
|
||||
console.error('Failed to generate updated paths:', pathsResult.error);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error updating paths:', error);
|
||||
}
|
||||
|
||||
isLoading = false;
|
||||
}
|
||||
|
||||
function hideThinkingPaths() {
|
||||
const thinkingPathsEl = document.getElementById('thinkingPaths');
|
||||
thinkingPathsEl.innerHTML = `
|
||||
<div class="thinking-indicator">Ask me a question and I'll show you different thinking approaches...</div>
|
||||
<div class="input-container">
|
||||
<input type="text" class="chat-input" id="chatInput" placeholder="Type your question..." onkeypress="handleKeyPress(event)">
|
||||
<button class="send-btn" id="sendBtn" onclick="sendMessage()">Send</button>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
function updateGuidedActions(actions) {
|
||||
// This function is no longer used in the new thinking paths system
|
||||
// Keeping it for backwards compatibility but it won't be called
|
||||
}
|
||||
|
||||
function handleAction(actionType) {
|
||||
// This function is no longer used in the new thinking paths system
|
||||
// Keeping it for backwards compatibility but it won't be called
|
||||
}
|
||||
|
||||
function sendQuickMessage(message) {
|
||||
document.getElementById('chatInput').value = message;
|
||||
sendMessage();
|
||||
}
|
||||
|
||||
function handleKeyPress(event) {
|
||||
if (event.key === 'Enter') {
|
||||
sendMessage();
|
||||
}
|
||||
}
|
||||
|
||||
// Focus input on load and add keyboard shortcuts
|
||||
window.addEventListener('load', () => {
|
||||
document.getElementById('chatInput').focus();
|
||||
});
|
||||
|
||||
// Global keyboard shortcuts
|
||||
document.addEventListener('keydown', (event) => {
|
||||
// Ctrl/Cmd + W to close
|
||||
if ((event.ctrlKey || event.metaKey) && event.key === 'w') {
|
||||
event.preventDefault();
|
||||
closeWindow();
|
||||
}
|
||||
|
||||
// Ctrl/Cmd + M to minimize
|
||||
if ((event.ctrlKey || event.metaKey) && event.key === 'm') {
|
||||
event.preventDefault();
|
||||
minimizeWindow();
|
||||
}
|
||||
|
||||
// F11 to toggle maximize
|
||||
if (event.key === 'F11') {
|
||||
event.preventDefault();
|
||||
toggleMaximize();
|
||||
}
|
||||
|
||||
// Ctrl/Cmd + R to update paths (if available)
|
||||
if ((event.ctrlKey || event.metaKey) && event.key === 'r' && document.getElementById('updatePathsBtn')) {
|
||||
event.preventDefault();
|
||||
updateThinkingPaths();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
348
LLM Desktop Chatbot Apps/ThinkPath-Chatbot-App/main.js
Normal file
348
LLM Desktop Chatbot Apps/ThinkPath-Chatbot-App/main.js
Normal file
|
|
@ -0,0 +1,348 @@
|
|||
const { app, BrowserWindow, ipcMain } = require('electron');
|
||||
const path = require('path');
|
||||
const axios = require('axios');
|
||||
|
||||
let mainWindow;
|
||||
|
||||
function createWindow() {
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 1200,
|
||||
height: 800,
|
||||
webPreferences: {
|
||||
nodeIntegration: true,
|
||||
contextIsolation: false
|
||||
},
|
||||
titleBarStyle: 'hidden',
|
||||
frame: false,
|
||||
minWidth: 800,
|
||||
minHeight: 600,
|
||||
icon: path.join(__dirname, 'assets/icon.png') // Optional: add an icon
|
||||
});
|
||||
|
||||
mainWindow.loadFile('index.html');
|
||||
|
||||
// Open DevTools in development
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
mainWindow.webContents.openDevTools();
|
||||
}
|
||||
}
|
||||
|
||||
// Window control handlers
|
||||
ipcMain.handle('window-minimize', () => {
|
||||
if (mainWindow) mainWindow.minimize();
|
||||
});
|
||||
|
||||
ipcMain.handle('window-maximize', () => {
|
||||
if (mainWindow) {
|
||||
if (mainWindow.isMaximized()) {
|
||||
mainWindow.unmaximize();
|
||||
} else {
|
||||
mainWindow.maximize();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
ipcMain.handle('window-close', () => {
|
||||
if (mainWindow) mainWindow.close();
|
||||
});
|
||||
|
||||
ipcMain.handle('window-is-maximized', () => {
|
||||
return mainWindow ? mainWindow.isMaximized() : false;
|
||||
});
|
||||
|
||||
// Ollama API communication
|
||||
ipcMain.handle('send-to-llm', async (event, message) => {
|
||||
try {
|
||||
const response = await axios.post('http://localhost:11434/api/generate', {
|
||||
model: 'gemma3:1b',
|
||||
prompt: message,
|
||||
stream: false
|
||||
});
|
||||
|
||||
return {
|
||||
success: true,
|
||||
response: response.data.response
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
success: false,
|
||||
error: error.message
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
// Generate updated thinking paths based on the current conversation context
|
||||
ipcMain.handle('generate-updated-paths', async (event, { originalQuery, lastResponse, conversationContext, lastPathName, lastStepsExecuted }) => {
|
||||
try {
|
||||
const prompt = `Based on this conversation context:
|
||||
|
||||
Original Question: "${originalQuery}"
|
||||
Last Approach Used: "${lastPathName}" (executed ${lastStepsExecuted} steps)
|
||||
Latest Response: "${lastResponse.substring(0, 500)}..."
|
||||
|
||||
Generate 4 NEW thinking approaches that logically continue from where we left off. These should be:
|
||||
1. Paths that build on the insights already gained
|
||||
2. Different perspectives or deeper exploration
|
||||
3. Next logical steps in the thinking process
|
||||
4. Alternative directions to explore
|
||||
|
||||
For each path, provide:
|
||||
1. A clear approach name (2-4 words)
|
||||
2. Exactly 3 specific thinking steps for that approach
|
||||
3. Make steps actionable and build on current progress
|
||||
|
||||
Format your response as JSON:
|
||||
{
|
||||
"paths": [
|
||||
{
|
||||
"name": "Continue Deep",
|
||||
"steps": ["Build on current insights", "Explore specific implications", "Develop concrete recommendations"]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Focus on continuation and progression rather than starting over.`;
|
||||
|
||||
const response = await axios.post('http://localhost:11434/api/generate', {
|
||||
model: 'gemma3:1b',
|
||||
prompt: prompt,
|
||||
stream: false
|
||||
});
|
||||
|
||||
// Try to parse JSON from response
|
||||
let parsedPaths;
|
||||
try {
|
||||
const jsonMatch = response.data.response.match(/\{[\s\S]*\}/);
|
||||
if (jsonMatch) {
|
||||
parsedPaths = JSON.parse(jsonMatch[0]);
|
||||
} else {
|
||||
throw new Error('No JSON found');
|
||||
}
|
||||
} catch (parseError) {
|
||||
// Fallback: generate contextual paths
|
||||
parsedPaths = generateContinuationPaths(lastPathName, lastStepsExecuted);
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
paths: parsedPaths.paths || []
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
success: false,
|
||||
paths: generateContinuationPaths(lastPathName, lastStepsExecuted),
|
||||
error: error.message
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
function generateContinuationPaths(lastPathName, lastStepsExecuted) {
|
||||
// Generate continuation paths based on what was just executed
|
||||
return {
|
||||
paths: [
|
||||
{
|
||||
name: "Continue Deep",
|
||||
steps: ["Build on current insights", "Explore specific implications", "Develop concrete recommendations"]
|
||||
},
|
||||
{
|
||||
name: "New Angle",
|
||||
steps: ["Approach from different perspective", "Challenge current assumptions", "Synthesize alternative view"]
|
||||
},
|
||||
{
|
||||
name: "Apply Practical",
|
||||
steps: ["Focus on implementation", "Address real-world constraints", "Create actionable plan"]
|
||||
},
|
||||
{
|
||||
name: "Expand Context",
|
||||
steps: ["Broaden the scope", "Connect to related domains", "Explore wider implications"]
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
ipcMain.handle('generate-thinking-paths', async (event, query) => {
|
||||
try {
|
||||
const prompt = `You are a strategic thinking assistant. For the following query: "${query}"
|
||||
|
||||
Generate 4 different thinking approaches/paths to solve this. For each path, provide:
|
||||
1. A clear approach name (2-4 words)
|
||||
2. Exactly 3 specific thinking steps for that approach
|
||||
3. Each step should be a concrete action or analysis
|
||||
|
||||
Format your response as JSON:
|
||||
{
|
||||
"paths": [
|
||||
{
|
||||
"name": "Approach Name",
|
||||
"steps": ["Step 1 description", "Step 2 description", "Step 3 description"]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Make the paths genuinely different approaches, not just variations. Think like a consultant presenting multiple strategies.`;
|
||||
|
||||
const response = await axios.post('http://localhost:11434/api/generate', {
|
||||
model: 'gemma3:1b',
|
||||
prompt: prompt,
|
||||
stream: false
|
||||
});
|
||||
|
||||
// Try to parse JSON from response
|
||||
let parsedPaths;
|
||||
try {
|
||||
// Extract JSON from the response (model might add extra text)
|
||||
const jsonMatch = response.data.response.match(/\{[\s\S]*\}/);
|
||||
if (jsonMatch) {
|
||||
parsedPaths = JSON.parse(jsonMatch[0]);
|
||||
} else {
|
||||
throw new Error('No JSON found');
|
||||
}
|
||||
} catch (parseError) {
|
||||
// Fallback: generate default paths
|
||||
parsedPaths = generateFallbackPaths(query);
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
paths: parsedPaths.paths || []
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
success: false,
|
||||
paths: generateFallbackPaths(query),
|
||||
error: error.message
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
// Execute a specific thinking path up to a certain step
|
||||
ipcMain.handle('execute-thinking-path', async (event, { query, pathName, steps, executeUpToStep }) => {
|
||||
try {
|
||||
let prompt = `Original question: "${query}"\n\nI'm following the "${pathName}" approach. I will execute these steps and structure my response to show my thinking process:\n\n`;
|
||||
|
||||
for (let i = 0; i < executeUpToStep; i++) {
|
||||
prompt += `Step ${i + 1}: ${steps[i]}\n`;
|
||||
}
|
||||
|
||||
prompt += `\nIMPORTANT: You must think through and execute ONLY the ${executeUpToStep} step${executeUpToStep > 1 ? 's' : ''} listed above. Do NOT go beyond these steps or provide a complete solution.
|
||||
|
||||
Structure your response exactly like this format:
|
||||
|
||||
**Following "${pathName}" Approach:**
|
||||
|
||||
**Step 1: ${steps[0] || 'First Step'}**
|
||||
[Think through and execute this specific step. Provide your actual reasoning, analysis, and findings for JUST this step. Be detailed but focused only on this step's scope.]
|
||||
|
||||
${executeUpToStep > 1 ? `**Step 2: ${steps[1] || 'Second Step'}**
|
||||
[Now execute step 2, building on step 1. Show your thinking process for this specific step. What new insights emerge? How does this advance from step 1?]` : ''}
|
||||
|
||||
${executeUpToStep > 2 ? `**Step 3: ${steps[2] || 'Third Step'}**
|
||||
[Execute the final step. Complete your analysis up to this point. What conclusions can you draw from steps 1-3?]` : ''}
|
||||
|
||||
**Current Progress:**
|
||||
[Summarize what you've accomplished in these ${executeUpToStep} step${executeUpToStep > 1 ? 's' : ''}. Note what still needs to be explored in future steps.]
|
||||
|
||||
REMEMBER: Only execute the steps you're asked to. Don't provide a complete answer - just show your thinking for the specified steps. Use **bold text** for important terms and bullet points for clarity.`;
|
||||
|
||||
const response = await axios.post('http://localhost:11434/api/generate', {
|
||||
model: 'gemma3:1b',
|
||||
prompt: prompt,
|
||||
stream: false
|
||||
});
|
||||
|
||||
return {
|
||||
success: true,
|
||||
response: response.data.response,
|
||||
pathName: pathName,
|
||||
stepsExecuted: executeUpToStep
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
success: false,
|
||||
error: error.message
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
function generateFallbackPaths(query) {
|
||||
const isCodeRelated = query.toLowerCase().includes('code') || query.toLowerCase().includes('program') || query.toLowerCase().includes('function');
|
||||
const isAnalysisRelated = query.toLowerCase().includes('analyz') || query.toLowerCase().includes('data') || query.toLowerCase().includes('research');
|
||||
|
||||
if (isCodeRelated) {
|
||||
return {
|
||||
paths: [
|
||||
{
|
||||
name: "Step by Step",
|
||||
steps: ["Break down requirements", "Design the algorithm", "Implement and test"]
|
||||
},
|
||||
{
|
||||
name: "Best Practices",
|
||||
steps: ["Research existing solutions", "Apply design patterns", "Optimize for performance"]
|
||||
},
|
||||
{
|
||||
name: "Quick Prototype",
|
||||
steps: ["Create minimal version", "Test core functionality", "Iterate and improve"]
|
||||
},
|
||||
{
|
||||
name: "Comprehensive",
|
||||
steps: ["Plan architecture", "Implement with documentation", "Add error handling"]
|
||||
}
|
||||
]
|
||||
};
|
||||
} else if (isAnalysisRelated) {
|
||||
return {
|
||||
paths: [
|
||||
{
|
||||
name: "Data Driven",
|
||||
steps: ["Gather relevant data", "Analyze patterns", "Draw conclusions"]
|
||||
},
|
||||
{
|
||||
name: "Comparative",
|
||||
steps: ["Identify alternatives", "Compare pros and cons", "Recommend best option"]
|
||||
},
|
||||
{
|
||||
name: "Root Cause",
|
||||
steps: ["Identify the problem", "Trace underlying causes", "Propose solutions"]
|
||||
},
|
||||
{
|
||||
name: "Strategic",
|
||||
steps: ["Define objectives", "Evaluate resources", "Create action plan"]
|
||||
}
|
||||
]
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
paths: [
|
||||
{
|
||||
name: "Analytical",
|
||||
steps: ["Break down the question", "Examine each component", "Synthesize insights"]
|
||||
},
|
||||
{
|
||||
name: "Creative",
|
||||
steps: ["Brainstorm possibilities", "Explore unconventional ideas", "Refine the best concepts"]
|
||||
},
|
||||
{
|
||||
name: "Practical",
|
||||
steps: ["Focus on implementation", "Consider real constraints", "Provide actionable steps"]
|
||||
},
|
||||
{
|
||||
name: "Comprehensive",
|
||||
steps: ["Research thoroughly", "Consider multiple perspectives", "Provide detailed analysis"]
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
app.whenReady().then(createWindow);
|
||||
|
||||
app.on('window-all-closed', () => {
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit();
|
||||
}
|
||||
});
|
||||
|
||||
app.on('activate', () => {
|
||||
if (BrowserWindow.getAllWindows().length === 0) {
|
||||
createWindow();
|
||||
}
|
||||
});
|
||||
4915
LLM Desktop Chatbot Apps/ThinkPath-Chatbot-App/package-lock.json
generated
Normal file
4915
LLM Desktop Chatbot Apps/ThinkPath-Chatbot-App/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
20
LLM Desktop Chatbot Apps/ThinkPath-Chatbot-App/package.json
Normal file
20
LLM Desktop Chatbot Apps/ThinkPath-Chatbot-App/package.json
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"name": "guided-llm-chat",
|
||||
"version": "1.0.0",
|
||||
"description": "Local LLM chat with guided responses",
|
||||
"main": "main.js",
|
||||
"scripts": {
|
||||
"start": "electron .",
|
||||
"dev": "concurrently \"npm run start\" \"npm run watch\"",
|
||||
"watch": "nodemon --exec npm run start",
|
||||
"build": "electron-builder"
|
||||
},
|
||||
"devDependencies": {
|
||||
"electron": "^27.0.0",
|
||||
"concurrently": "^8.2.0",
|
||||
"nodemon": "^3.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": "^1.6.0"
|
||||
}
|
||||
}
|
||||
261
LLM Desktop Chatbot Apps/ThinkPath-Chatbot-App/readme.md
Normal file
261
LLM Desktop Chatbot Apps/ThinkPath-Chatbot-App/readme.md
Normal file
|
|
@ -0,0 +1,261 @@
|
|||
# ThinkPath Chatbot 🧠
|
||||
*Strategic Thinking Assistant with Local LLM Integration*
|
||||
*Guided Responses Chatbot*
|
||||
|
||||
[](https://opensource.org/licenses/MIT)
|
||||
[](https://nodejs.org/)
|
||||
[](https://electronjs.org/)
|
||||
[](https://ollama.ai/)
|
||||
|
||||
> **Stop over-generating. Start thinking strategically.**
|
||||
|
||||
ThinkPath AI revolutionizes how you interact with language models by introducing **guided thinking paths** - letting you control exactly how deep the AI goes into any topic, step by step.
|
||||
|
||||

|
||||
<video width="100%" controls>
|
||||
<source src="https://github.com/Ahmed-G-ElTaher/ThinkPath-Chatbot/blob/main/github%20thinkpath%20video.mp4" type="video/mp4">
|
||||
Your browser does not support the video tag.
|
||||
</video>
|
||||
|
||||
|
||||
## 🎯 **The Problem We Solve**
|
||||
|
||||
### Before ThinkPath AI:
|
||||
- ❌ **Token Waste**: AI generates full responses when you only need part of the analysis
|
||||
- ❌ **Over-Information**: Getting overwhelmed with details you didn't ask for
|
||||
- ❌ **No Control**: Can't pause AI mid-thought to explore different directions
|
||||
- ❌ **Linear Thinking**: Stuck with one approach, can't easily switch perspectives
|
||||
- ❌ **High Costs**: Paying for tokens you don't need or want
|
||||
|
||||
### With ThinkPath AI:
|
||||
- ✅ **Precision Control**: Get exactly the depth of analysis you need
|
||||
- ✅ **Cost Efficiency**: Pay only for the thinking steps you choose
|
||||
- ✅ **Strategic Flexibility**: Switch between different approaches dynamically
|
||||
- ✅ **Incremental Discovery**: Build understanding step-by-step
|
||||
- ✅ **Complete Privacy**: Everything runs locally on your machine
|
||||
|
||||
## 🚀 **Key Features**
|
||||
|
||||
### 🧭 **Guided Thinking Paths**
|
||||
- **Dynamic Path Generation**: AI creates 4 different thinking approaches for each question
|
||||
- **Step-by-Step Execution**: Click any step to execute that approach up to that point
|
||||
- **Cumulative Logic**: Step 3 = Steps 1 + 2 + 3 executed together
|
||||
- **Visual Progress**: See exactly which steps have been completed
|
||||
|
||||
### 🔄 **Adaptive Conversation**
|
||||
- **Auto-Path Updates**: New thinking approaches generated after each response
|
||||
- **Context Awareness**: Paths build on conversation history
|
||||
- **Continuation Focus**: Next steps always relevant to current progress
|
||||
|
||||
### 🎨 **Professional Interface**
|
||||
- **Modern Design**: Clean, intuitive interface inspired by professional tools
|
||||
- **Window Controls**: Native minimize, maximize, close buttons
|
||||
- **Structured Responses**: Bold text, bullet points, professional formatting
|
||||
- **Keyboard Shortcuts**: Fast navigation and control
|
||||
|
||||
### 🔒 **Complete Privacy**
|
||||
- **Local Processing**: All AI runs on your machine via Ollama
|
||||
- **No Data Sharing**: Conversations never leave your computer
|
||||
- **Offline Capable**: Works without internet connection
|
||||
- **Model Choice**: Use any Ollama-compatible model (Llama, Gemma, etc.)
|
||||
|
||||
## 📊 **Cost Comparison**
|
||||
|
||||
| Scenario | Traditional Chat | ThinkPath AI | Savings |
|
||||
|----------|-----------------|--------------|---------|
|
||||
| Quick clarification | 500 tokens | 150 tokens | **70%** |
|
||||
| Partial analysis | 1200 tokens | 400 tokens | **67%** |
|
||||
| Exploring options | 2000 tokens | 600 tokens | **70%** |
|
||||
| Complex strategy | 3500 tokens | 1000 tokens | **71%** |
|
||||
|
||||
*Based on typical usage patterns where users only need partial analysis*
|
||||
|
||||
## 🛠 **Installation**
|
||||
|
||||
### Prerequisites
|
||||
- [Node.js](https://nodejs.org/) (v18 or higher)
|
||||
- [Ollama](https://ollama.ai/) installed and running
|
||||
- At least one language model downloaded
|
||||
|
||||
### Quick Start
|
||||
|
||||
1. **Clone the repository**
|
||||
```bash
|
||||
git clone https://github.com/Ahmed-G-ElTaher/ThinkPath-Chatbot.git
|
||||
cd thinkpath-ai
|
||||
```
|
||||
|
||||
2. **Install dependencies**
|
||||
```bash
|
||||
npm install
|
||||
```
|
||||
|
||||
3. **Setup Ollama and download a model**
|
||||
```bash
|
||||
# Install Ollama (if not already installed)
|
||||
# Visit https://ollama.ai/download
|
||||
|
||||
# Download a fast model
|
||||
ollama pull gemma3:1b
|
||||
|
||||
# Or a more capable model
|
||||
ollama pull llama3.1:8b
|
||||
```
|
||||
|
||||
4. **Configure the model** (if needed)
|
||||
```bash
|
||||
# Edit main.js line 45 to match your model
|
||||
model: 'gemma3:1b' # Change to your preferred model
|
||||
```
|
||||
|
||||
5. **Run the application**
|
||||
```bash
|
||||
npm start
|
||||
```
|
||||
|
||||
## 💡 **How It Works**
|
||||
|
||||
### 1. **Ask Any Question**
|
||||
Type your question and ThinkPath AI generates 4 different thinking approaches:
|
||||
- Analytical, Creative, Practical, Comprehensive
|
||||
- Or context-specific paths like "Technical Deep Dive", "Business Impact", etc.
|
||||
|
||||
### 2. **Choose Your Path & Step**
|
||||
Each approach has 3 steps. Click any step to execute that path up to that point:
|
||||
- Step 1: Execute just the first step
|
||||
- Step 2: Execute steps 1 and 2
|
||||
- Step 3: Execute all three steps
|
||||
|
||||
### 3. **Get Structured Responses**
|
||||
AI provides detailed analysis with:
|
||||
- Clear step-by-step breakdown
|
||||
- Bold key terms and concepts
|
||||
- Bullet points for clarity
|
||||
- Progress summary
|
||||
|
||||
### 4. **Continue Exploring**
|
||||
After each response, new thinking paths automatically appear, building on your conversation context.
|
||||
|
||||
## 🎯 **Use Cases**
|
||||
|
||||
### 💻 **Software Development & Debugging**
|
||||
- Model debugging with controllable depth of analysis
|
||||
- Architecture planning with multiple technical approaches
|
||||
- Code review with focused, step-by-step examination
|
||||
- Performance optimization with systematic investigation
|
||||
|
||||
### 🤖 **Machine Learning & AI**
|
||||
- Training issue diagnosis without information overflow
|
||||
- Hyperparameter tuning with guided experimentation
|
||||
- Model architecture exploration step by step
|
||||
- Data pipeline debugging with structured approaches
|
||||
|
||||
### 📊 **Data Science**
|
||||
- Exploratory data analysis with multiple perspectives
|
||||
- Feature engineering with incremental discovery
|
||||
- Statistical analysis with controlled complexity
|
||||
- Visualization planning with step-by-step breakdown
|
||||
|
||||
### 💼 **Technical Leadership**
|
||||
- System architecture decisions with guided analysis
|
||||
- Technology stack evaluation with structured comparison
|
||||
- Technical debt assessment with focused investigation
|
||||
- Team problem-solving with methodical approaches
|
||||
|
||||
## ⚙️ **Configuration**
|
||||
|
||||
### Model Selection
|
||||
Edit `main.js` to use different models:
|
||||
```javascript
|
||||
// Line 45: Change the model name
|
||||
model: 'llama3.1:8b' // or 'gemma3:1b', 'mistral:7b', etc.
|
||||
```
|
||||
|
||||
### UI Customization
|
||||
Modify `index.html` CSS for:
|
||||
- Color schemes
|
||||
- Typography
|
||||
- Layout preferences
|
||||
- Window styling
|
||||
|
||||
### Keyboard Shortcuts
|
||||
- `Ctrl/Cmd + W` - Close window
|
||||
- `Ctrl/Cmd + M` - Minimize window
|
||||
- `F11` - Toggle maximize
|
||||
- `Ctrl/Cmd + R` - Refresh thinking paths
|
||||
|
||||
## 🔮 **Future Development**
|
||||
|
||||
### 🎯 **Planned Features**
|
||||
- [ ] **Multi-Model Support**: Run multiple models simultaneously for different perspectives
|
||||
- [ ] **Custom Thinking Templates**: Create and save your own thinking approaches
|
||||
- [ ] **Conversation Export**: Save thinking sessions as structured documents
|
||||
- [ ] **Voice Integration**: Speech-to-text for natural interaction
|
||||
- [ ] **Team Collaboration**: Share thinking sessions with team members
|
||||
- [ ] **Analytics Dashboard**: Track thinking patterns and productivity
|
||||
- [ ] **Plugin System**: Extend functionality with custom tools
|
||||
- [ ] **Mobile App**: iOS/Android versions with cloud sync
|
||||
|
||||
### 🏗 **Potential Applications**
|
||||
|
||||
#### 🎓 **Education Sector**
|
||||
- **Socratic Learning Platform**: Guide students through step-by-step problem solving
|
||||
- **Research Assistant**: Help students explore topics with structured thinking
|
||||
- **Thesis Planning**: Break down complex research into manageable steps
|
||||
|
||||
#### 🏥 **Healthcare**
|
||||
- **Diagnostic Support**: Multi-approach medical analysis (symptoms → differential → testing)
|
||||
- **Treatment Planning**: Step-by-step care plan development
|
||||
- **Medical Education**: Case-based learning with guided analysis
|
||||
|
||||
#### ⚖️ **Legal**
|
||||
- **Case Analysis**: Multiple legal approaches to complex cases
|
||||
- **Contract Review**: Systematic document analysis
|
||||
- **Legal Research**: Structured exploration of legal precedents
|
||||
|
||||
#### 🏭 **Enterprise**
|
||||
- **Decision Support**: Strategic planning with guided thinking
|
||||
- **Risk Assessment**: Multi-perspective risk analysis
|
||||
- **Training Programs**: Skill development with structured learning
|
||||
|
||||
#### 🔬 **Research & Development**
|
||||
- **Scientific Method**: Hypothesis → Experiment → Analysis workflows
|
||||
- **Innovation Labs**: Systematic ideation and validation
|
||||
- **Patent Analysis**: Multi-angle IP research
|
||||
|
||||
## 🤝 **Contributing**
|
||||
|
||||
We welcome contributions! Here's how you can help:
|
||||
|
||||
1. **Fork the repository**
|
||||
2. **Create a feature branch**: `git checkout -b feature/amazing-feature`
|
||||
3. **Commit changes**: `git commit -m 'Add amazing feature'`
|
||||
4. **Push to branch**: `git push origin feature/amazing-feature`
|
||||
5. **Open a Pull Request**
|
||||
|
||||
### Development Areas
|
||||
- **UI/UX Improvements**: Better visual design and user experience
|
||||
- **Model Integration**: Support for new LLM providers
|
||||
- **Performance**: Optimization for faster response times
|
||||
- **Features**: New thinking methodologies and tools
|
||||
- **Documentation**: Tutorials, guides, and examples
|
||||
|
||||
## 📝 **License**
|
||||
|
||||
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
||||
|
||||
## 🙏 **Acknowledgments**
|
||||
|
||||
- **Ollama**: For making local LLM deployment accessible
|
||||
- **Electron**: For cross-platform desktop app framework
|
||||
- **AI Community**: For advancing open-source language models
|
||||
- **Strategic Thinking**: Inspired by consulting methodologies and structured problem-solving
|
||||
|
||||
|
||||
---
|
||||
|
||||
**Built with ❤️ for strategic thinkers who value precision, privacy, and control.**
|
||||
|
||||
*Stop over-generating. Start thinking strategically with ThinkPath AI.*
|
||||
|
||||
**Developed in collaboration with Claude AI** - demonstrating that the future of software development lies in thoughtful human-AI partnership, where AI amplifies human creativity and strategic thinking rather than replacing it. 🤖🤝👨💻
|
||||
Loading…
Reference in a new issue