feat: improve chatbot planning responses

This commit is contained in:
renato97
2025-12-01 03:07:24 +00:00
parent a87347475a
commit 69779a4bdb
4 changed files with 358 additions and 5 deletions

View File

@@ -333,7 +333,7 @@
"order": 0,
"width": "12",
"height": "10",
"format": "\n<md-card class=\"chatbot-card\">\n <md-card-title>\n <span class=\"md-headline\">Chatbot ALS</span>\n </md-card-title>\n <md-card-content>\n <div class=\"chat-log\">\n <div ng-repeat=\"item in messages\" class=\"message {{item.role}}\">\n <strong>{{item.role === 'user' ? 'T\u00fa' : (item.role === 'bot' ? 'ALS Bot' : 'Error')}}:</strong>\n <span>{{item.text}}</span>\n </div>\n </div>\n <form ng-submit=\"sendMessage()\">\n <md-input-container class=\"md-block\">\n <label>Escribe algo (ej. generame un als de reggaeton 2001)</label>\n <input ng-model=\"promptText\" required ng-disabled=\"busy\" />\n </md-input-container>\n <md-button class=\"md-raised md-primary\" type=\"submit\" ng-disabled=\"busy\">{{busy ? 'Generando...' : 'Enviar'}}</md-button>\n </form>\n </md-card-content>\n</md-card>\n<script>\n(function(scope) {\n scope.messages = [];\n scope.promptText = '';\n scope.busy = false;\n function pushMessage(role, text) {\n scope.messages.push({ role: role, text: text });\n if (scope.messages.length > 50) {\n scope.messages.shift();\n }\n scope.$applyAsync();\n }\n scope.sendMessage = function() {\n if (!scope.promptText || scope.busy) { return; }\n const text = scope.promptText;\n scope.promptText = '';\n pushMessage('user', text);\n scope.busy = true;\n fetch('/als/chat', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ prompt: text })\n })\n .then(function(res) {\n return res.text().then(function(body) {\n var data;\n try { data = body ? JSON.parse(body) : {}; } catch (err) { data = { error: body || err.message }; }\n return { ok: res.ok, data: data };\n });\n })\n .then(function(result) {\n if (result.ok) {\n var message = 'Proyecto: ' + result.data.projectName + '. Archivo: ' + result.data.outputPath;\n pushMessage('bot', message);\n } else {\n pushMessage('error', result.data && result.data.error ? result.data.error : 'Error generando ALS');\n }\n })\n .catch(function(err) {\n pushMessage('error', err.message || 'Error inesperado');\n })\n .finally(function() {\n scope.busy = false;\n scope.$applyAsync();\n });\n };\n})(scope);\n</script>\n<style>\n .chatbot-card .chat-log {\n max-height: 260px;\n overflow-y: auto;\n margin-bottom: 12px;\n padding: 8px;\n background: rgba(0,0,0,0.05);\n border-radius: 6px;\n }\n .chatbot-card .message { margin-bottom: 6px; }\n .chatbot-card .message.user strong { color: #1976d2; }\n .chatbot-card .message.bot strong { color: #2e7d32; }\n .chatbot-card .message.error strong { color: #c62828; }\n</style>\n",
"format": "\n<md-card class=\"chatbot-card\">\n <md-card-title>\n <span class=\"md-headline\">Chatbot ALS</span>\n </md-card-title>\n <md-card-content>\n <div class=\"chat-log\">\n <div ng-repeat=\"item in messages\" class=\"message {{item.role}}\">\n <strong>{{item.role === 'user' ? 'T\u00fa' : (item.role === 'bot' ? 'ALS Bot' : 'Error')}}:</strong>\n <span>{{item.text}}</span>\n </div>\n </div>\n <form ng-submit=\"sendMessage()\">\n <md-input-container class=\"md-block\">\n <label>Escribe algo (ej. generame un als de reggaeton 2001)</label>\n <input ng-model=\"promptText\" required ng-disabled=\"busy\" />\n </md-input-container>\n <md-button class=\"md-raised md-primary\" type=\"submit\" ng-disabled=\"busy\">{{busy ? 'Generando...' : 'Enviar'}}</md-button>\n </form>\n </md-card-content>\n</md-card>\n<script>\n(function(scope) {\n scope.messages = [];\n scope.promptText = '';\n scope.busy = false;\n function pushMessage(role, text) {\n scope.messages.push({ role: role, text: text });\n if (scope.messages.length > 50) {\n scope.messages.shift();\n }\n scope.$applyAsync();\n }\n scope.sendMessage = function() {\n if (!scope.promptText || scope.busy) { return; }\n const text = scope.promptText;\n scope.promptText = '';\n pushMessage('user', text);\n scope.busy = true;\n fetch('/als/chat', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ prompt: text })\n })\n .then(function(res) {\n return res.text().then(function(body) {\n var data;\n try { data = body ? JSON.parse(body) : {}; } catch (err) { data = { error: body || err.message }; }\n return { ok: res.ok, data: data };\n });\n })\n .then(function(result) {\n if (result.ok) {\n if (result.data && result.data.projectName) {\n var message = 'Proyecto generado: ' + result.data.projectName + '. Archivo: ' + result.data.outputPath;\n pushMessage('bot', message);\n } else if (result.data && result.data.reply) {\n pushMessage('bot', result.data.reply);\n } else {\n pushMessage('bot', 'Listo. \u00bfQuieres que genere un ALS?');\n }\n } else {\n pushMessage('error', result.data && result.data.error ? result.data.error : 'Error generando ALS');\n }\n })\n .catch(function(err) {\n pushMessage('error', err.message || 'Error inesperado');\n })\n .finally(function() {\n scope.busy = false;\n scope.$applyAsync();\n });\n };\n})(scope);\n</script>\n<style>\n .chatbot-card .chat-log {\n max-height: 260px;\n overflow-y: auto;\n margin-bottom: 12px;\n padding: 8px;\n background: rgba(0,0,0,0.05);\n border-radius: 6px;\n }\n .chatbot-card .message { margin-bottom: 6px; }\n .chatbot-card .message.user strong { color: #1976d2; }\n .chatbot-card .message.bot strong { color: #2e7d32; }\n .chatbot-card .message.error strong { color: #c62828; }\n</style>\n",
"storeOutMessages": false,
"fwdInMessages": false,
"resendOnRefresh": true,
@@ -365,7 +365,7 @@
"type": "function",
"z": "f68df1c4d2e4e1a9",
"name": "Chatbot ALS",
"func": "\nconst raw = typeof msg.payload === 'string' ? msg.payload : JSON.stringify(msg.payload || {});\nlet body = {};\ntry {\n body = typeof msg.payload === 'object' ? msg.payload : JSON.parse(raw);\n} catch (err) {\n body = {};\n}\nconst prompt = (body.prompt || body.message || msg.prompt || '').trim();\nif (!prompt) {\n msg.statusCode = 400;\n msg.payload = { error: 'Falta el prompt del chatbot.' };\n return msg;\n}\nconst generator = global.get('alsGenerator');\nif (!generator || typeof generator.generateFromPrompt !== 'function') {\n msg.statusCode = 500;\n msg.payload = { error: 'Generador no disponible.' };\n return msg;\n}\nreturn (async () => {\n try {\n const result = await generator.generateFromPrompt(prompt);\n msg.statusCode = 200;\n msg.payload = {\n prompt: prompt,\n projectName: result.plan.projectName,\n templateHash: result.plan.templateHash,\n outputPath: result.outputPath,\n registered: result.registered\n };\n return msg;\n } catch (err) {\n node.error(err.message, msg);\n msg.statusCode = 500;\n msg.payload = { error: err.message };\n return msg;\n }\n})();\n",
"func": "\nconst raw = typeof msg.payload === 'string' ? msg.payload : JSON.stringify(msg.payload || {});\nlet body = {};\ntry {\n body = typeof msg.payload === 'object' ? msg.payload : JSON.parse(raw);\n} catch (err) {\n body = {};\n}\nconst prompt = (body.prompt || body.message || msg.prompt || '').trim();\nif (!prompt) {\n msg.statusCode = 400;\n msg.payload = { error: 'Falta el prompt del chatbot.' };\n return msg;\n}\nconst generator = global.get('alsGenerator');\nif (!generator || typeof generator.generateFromPrompt !== 'function') {\n msg.statusCode = 500;\n msg.payload = { error: 'Generador no disponible.' };\n return msg;\n}\nfunction shouldGenerate(text) {\n return /(genera(me)?|crea(me)?|haz(me)?|arma(me)?|produce(me)?).*(als|ableton|beat|proyecto)/i.test(text);\n}\nfunction buildSummary(text, library, sources) {\n if (!library || !library.length) {\n return 'A\u00fan no tengo proyectos cargados. Sube un .als primero y luego dime \"generame un als ...\" para empezar.';\n }\n const recent = library.slice(-1)[0];\n const parts = [\n `Tengo ${library.length} proyectos almacenados. El \u00faltimo fue \"${recent.projectName}\" a ${recent.liveSet?.tempo || 'N/D'} BPM.`,\n sources && sources.length ? `Hay ${sources.length} recursos en sources (ej: ${sources.slice(0,3).join(', ')})` : 'A\u00fan no hay archivos en data/sources/.',\n 'Cuando est\u00e9s listo dime algo como \"generame un als afrohouse 2025 con 124 bpm\" y preparo la sesi\u00f3n.'\n ];\n return parts.join(' ');\n}\nif (!shouldGenerate(prompt)) {\n const info = generator.listLibrary ? generator.listLibrary() : [];\n const sources = generator.listSources ? generator.listSources() : [];\n msg.statusCode = 200;\n msg.payload = { reply: buildSummary(prompt, info, sources) };\n return msg;\n}\nreturn (async () => {\n try {\n const result = await generator.generateFromPrompt(prompt);\n msg.statusCode = 200;\n msg.payload = {\n prompt: prompt,\n projectName: result.plan.projectName,\n templateHash: result.plan.templateHash,\n outputPath: result.outputPath,\n registered: result.registered\n };\n return msg;\n } catch (err) {\n node.error(err.message, msg);\n msg.statusCode = 500;\n msg.payload = { error: err.message };\n return msg;\n }\n})();\n",
"outputs": 1,
"noerr": 0,
"initialize": "",