aboutsummaryrefslogtreecommitdiff
path: root/chat/chat-commands.js
diff options
context:
space:
mode:
authorAgando <roduccomm@gmail.com>2026-05-30 18:01:51 +0200
committerAgando <roduccomm@gmail.com>2026-05-30 18:01:51 +0200
commitd8bf7fa398d6d928325be9b5c64ca24875bfeef8 (patch)
tree49ee4b3586ad68c648d546e6831abc30d8576be5 /chat/chat-commands.js
parente3fb2d434c4f7317944b7c77781599528d766a39 (diff)
auto: 2026-05-30_18:00 changes
Diffstat (limited to 'chat/chat-commands.js')
-rw-r--r--chat/chat-commands.js276
1 files changed, 276 insertions, 0 deletions
diff --git a/chat/chat-commands.js b/chat/chat-commands.js
new file mode 100644
index 0000000..d5cfdd9
--- /dev/null
+++ b/chat/chat-commands.js
@@ -0,0 +1,276 @@
+/*
+ * Version: 1.0.0-lite
+ * ChatStudio Lite - Command Handlers
+ * Handles /search, /fetch, /explain, /help, /status, /clear, /modules, etc.
+ */
+
+async function handleCommand(cmd) {
+ var parts = cmd.split(' ');
+ var command = parts[0].toLowerCase();
+ var args = parts.slice(1).join(' ');
+
+ // === /help ===
+ if (command === '/help' || command === '?') {
+ addMessage('ai',
+ '**ChatStudio Lite v' + CHATSTUDIO_VERSION + '**\n\n' +
+ '**Built-in Commands:**\n' +
+ '`/help` or `?` — Show this help\n' +
+ '`/module [name]` — Switch AI module\n' +
+ '`/modules` — List all modules\n' +
+ '`/search [query]` — Web search via DuckDuckGo (with AI overview)\n' +
+ '`/fetch [url]` — Fetch and display a web page\n' +
+ '`/extract [url]` — Extract readable content from a URL\n' +
+ '`/summarize [url]` — AI summarization of a URL\n' +
+ '`/explain [code]` — Get AI code explanation\n' +
+ '`/status` — Check Ollama connection status\n' +
+ '`/test` — Ping the AI API\n' +
+ '`/models` — List all available AI models\n' +
+ '`/clear` or `/purge` — Clear chat history\n\n' +
+ '**Modules:**\n' +
+ 'Modules in the sidebar customize AI behavior. Each module has a system prompt and commands.\n' +
+ 'Use `/module [name]` to switch, or edit them from the sidebar.\n\n' +
+ '**Links:**\n' +
+ '<a href="/spaces/chatstudio/">Full ChatStudio (Pro)</a>\n' +
+ '<a href="/spaces/dashboard.html">User Dashboard</a>\n\n' +
+ 'Type any question to chat with the AI!'
+ );
+ return;
+ }
+
+ // === /module or /switch ===
+ if (command === '/module' || command === '/switch') {
+ var target = args.toLowerCase();
+ var found = modules.find(function (m) {
+ return m.id === target || m.name.toLowerCase().includes(target);
+ });
+ if (found) {
+ switchModule(found.id);
+ addMessage('ai', 'Switched to ' + found.name + ' module!');
+ } else {
+ addMessage('ai', 'Module not found. Available: ' + modules.map(function (m) { return m.name; }).join(', '));
+ }
+ return;
+ }
+
+ // === /modules or /list ===
+ if (command === '/modules' || command === '/list' || command === '/mods') {
+ addMessage('ai', '**Available Modules:**\n\n' +
+ modules.map(function (m) { return '- **' + m.name + '** - ' + m.desc; }).join('\n'));
+ return;
+ }
+
+ // === /explain ===
+ if (command === '/explain' && args) {
+ showTyping();
+ try {
+ var headers = { 'Content-Type': 'application/json' };
+ if (typeof OLLAMA_API_KEY !== 'undefined' && OLLAMA_API_KEY) {
+ headers['Authorization'] = 'Bearer ' + OLLAMA_API_KEY;
+ }
+ var response = await fetch((typeof OLLAMA_URL !== 'undefined' ? OLLAMA_URL : '/ollama') + '/api/generate', {
+ method: 'POST',
+ headers: headers,
+ body: JSON.stringify({
+ model: document.getElementById('modelSelect').value,
+ prompt: 'Explain this code clearly, line by line, what it does:\n\n' + args,
+ stream: false
+ })
+ });
+ hideTyping();
+ var data = await response.json();
+ addMessage('ai', '**Code Explanation:**\n\n' + (data.response || 'No response'));
+ } catch (e) {
+ hideTyping();
+ addMessage('ai', 'Failed to explain code: ' + e.message);
+ }
+ return;
+ }
+
+ // === /search or /find ===
+ if (command === '/search' || command === '/find') {
+ var query = args || cmd.split(' ').slice(1).join(' ');
+ if (!query) {
+ addMessage('ai', 'Usage: /search [query]\n\nExample: /search Python tutorials');
+ return;
+ }
+ showTyping();
+ try {
+ var response = await fetch('/api/search?q=' + encodeURIComponent(query) + '&summarize=true');
+ var data = await response.json();
+ hideTyping();
+ if (data.error) {
+ addMessage('ai', 'Search failed: ' + data.error);
+ return;
+ }
+ if (data.results && data.results.length > 0) {
+ var source = data.source === 'searxng' ? '🔍 (SearXNG)' : '🔍 (DDG)';
+ var msg = '';
+ if (data.ai_overview) {
+ msg += '🌿 **AI Overview:**\n' + data.ai_overview + '\n\n---\n\n';
+ }
+ msg += source + ' **Search results for "' + query + '":**\n\n';
+ data.results.slice(0, 10).forEach(function(r) {
+ msg += '• **' + (r.title || 'Untitled') + '**\n';
+ msg += ' ' + (r.url || '') + '\n';
+ if (r.content && r.content.length > 5) {
+ msg += ' _' + r.content.substring(0, 200) + (r.content.length > 200 ? '...' : '') + '_\n';
+ }
+ msg += '\n';
+ });
+ if (data.count > 10) {
+ msg += '_... and ' + (data.count - 10) + ' more results_\n';
+ }
+ addMessage('ai', msg);
+ } else {
+ addMessage('ai', '🔍 No results found for "' + query + '".');
+ }
+ } catch (e) {
+ hideTyping();
+ addMessage('ai', 'Search failed: ' + e.message);
+ }
+ return;
+ }
+
+ // === /fetch or /get ===
+ if (command === '/fetch' || command === '/get') {
+ var url = args || (cmd.match(/(https?:\/\/[^\s]+)/) ? cmd.match(/(https?:\/\/[^\s]+)/)[1] : null);
+ if (!url) {
+ addMessage('ai', 'Usage: /fetch [url]\n\nExample: /fetch https://example.com');
+ return;
+ }
+ showTyping();
+ try {
+ var extractResp = await fetch('/api/extract?url=' + encodeURIComponent(url));
+ var extractOk = extractResp.ok;
+ var extractData = extractOk ? await extractResp.json() : null;
+
+ var htmlResp = await fetch('/api/fetch?url=' + encodeURIComponent(url));
+ if (!htmlResp.ok) throw new Error('HTTP ' + htmlResp.status);
+ var html = await htmlResp.text();
+ var htmlPreview = html.substring(0, 262144) + (html.length > 262144 ? '\n\n... (truncated)' : '');
+
+ hideTyping();
+ var msg = '';
+ if (extractData && !extractData.error) {
+ msg += '📄 **Fetched:** ' + extractData.url + '\n\n';
+ if (extractData.title) msg += '**Title:** ' + extractData.title + '\n';
+ msg += '**Words:** ' + (extractData.word_count || '?') + '\n';
+ msg += '**Method:** ' + (extractData.method || '?') + '\n';
+ if (extractData.excerpt) msg += '\n**Preview:**\n' + extractData.excerpt + '\n';
+ } else {
+ msg += '📄 **Fetched:** ' + url + '\n';
+ }
+ msg += '\n--- Raw HTML (truncated) ---\n```html\n' + htmlPreview + '\n```';
+ addMessage('ai', msg);
+ } catch (e) {
+ hideTyping();
+ addMessage('ai', 'Fetch failed: ' + e.message);
+ }
+ return;
+ }
+
+ // === /summarize ===
+ if (command === '/summarize') {
+ var url = args || (cmd.match(/(https?:\/\/[^\s]+)/) ? cmd.match(/(https?:\/\/[^\s]+)/)[1] : null);
+ if (!url) {
+ addMessage('ai', 'Usage: /summarize [url]\n\nExample: /summarize https://example.com');
+ return;
+ }
+ showTyping();
+ try {
+ var response = await fetch('/api/summarize?url=' + encodeURIComponent(url));
+ if (!response.ok) throw new Error('HTTP ' + response.status);
+ var data = await response.json();
+ hideTyping();
+ var msg = '🤖 **AI Summary**\n';
+ if (data.summary) {
+ msg += '\n' + data.summary + '\n';
+ }
+ msg += '\n_Model: ' + (data.model || 'gemma4:31b-cloud') + ' | Processed in ' + (data.processing_time_ms || '?') + 'ms_';
+ addMessage('ai', msg);
+ } catch (e) {
+ hideTyping();
+ addMessage('ai', 'Summarize failed: ' + e.message);
+ }
+ return;
+ }
+
+ // === /extract ===
+ if (command === '/extract') {
+ var url = args || (cmd.match(/(https?:\/\/[^\s]+)/) ? cmd.match(/(https?:\/\/[^\s]+)/)[1] : null);
+ if (!url) {
+ addMessage('ai', 'Usage: /extract [url]\n\nExample: /extract https://example.com');
+ return;
+ }
+ showTyping();
+ try {
+ var response = await fetch('/api/extract?url=' + encodeURIComponent(url));
+ if (!response.ok) throw new Error('HTTP ' + response.status);
+ var data = await response.json();
+ hideTyping();
+ var msg = '📄 **Extracted:** ' + (data.url || url) + '\n\n';
+ if (data.title) msg += '**Title:** ' + data.title + '\n';
+ msg += '**Words:** ' + (data.word_count || '?') + '\n';
+ msg += '**Method:** ' + (data.method || '?') + '\n';
+ if (data.excerpt) msg += '\n**Preview:**\n' + data.excerpt + '\n';
+ if (data.content) msg += '\n**Full Content:** (first 2000 chars)\n' + data.content.substring(0, 2000) + (data.content.length > 2000 ? '...' : '') + '\n';
+ addMessage('ai', msg);
+ } catch (e) {
+ hideTyping();
+ addMessage('ai', 'Extract failed: ' + e.message);
+ }
+ return;
+ }
+
+ // === /status ===
+ if (command === '/status') {
+ try {
+ var response = await fetch((typeof OLLAMA_URL !== 'undefined' ? OLLAMA_URL : '/ollama') + '/api/tags');
+ var data = await response.json();
+ var modelCount = data.models ? data.models.length : 0;
+ var current = document.getElementById('modelSelect').value;
+ addMessage('ai', '**Ollama Status**\n\n- Status: Online\n- Available models: ' + modelCount + '\n- Current model: ' + current + '\n- API: ' + (typeof OLLAMA_URL !== 'undefined' ? OLLAMA_URL : '/ollama'));
+ } catch (e) {
+ addMessage('ai', '**Ollama Status**\n\n- Status: Offline\n- Error: ' + e.message);
+ }
+ return;
+ }
+
+ // === /test ===
+ if (command === '/test') {
+ showTyping();
+ try {
+ var start = Date.now();
+ var response = await fetch((typeof OLLAMA_URL !== 'undefined' ? OLLAMA_URL : '/ollama') + '/api/tags');
+ var ms = Date.now() - start;
+ hideTyping();
+ addMessage('ai', '**Connection Test**\n\n- Response time: ' + ms + 'ms\n- Status: OK');
+ } catch (e) {
+ hideTyping();
+ addMessage('ai', '**Connection Test Failed**\n\n- Error: ' + e.message);
+ }
+ return;
+ }
+
+ // === /models or /list models ===
+ if (command === '/models') {
+ try {
+ var response = await fetch((typeof OLLAMA_URL !== 'undefined' ? OLLAMA_URL : '/ollama') + '/api/tags');
+ var data = await response.json();
+ var list = data.models ? data.models.map(function (m) { return '- ' + m.name; }).join('\n') : 'No models';
+ addMessage('ai', '**Available Models:**\n\n' + list);
+ } catch (e) {
+ addMessage('ai', 'Failed to list models: ' + e.message);
+ }
+ return;
+ }
+
+ // === /clear, /purge ===
+ if (command === '/clear' || command === '/purge') {
+ clearChat();
+ return;
+ }
+
+ // Unknown command
+ addMessage('ai', 'Unknown command. Try /help, /modules, /explain [code], /search [query], /summarize [url], /extract [url], /fetch [url], /status, /test, /models, or /switch [name]');
+}