feat: improve chatbot planning responses
This commit is contained in:
@@ -514,5 +514,349 @@
|
||||
},
|
||||
"storedAt": "2025-12-01T03:02:37.033Z",
|
||||
"filePath": "library/38427f49e8ffcfba20969319b9dda2f7.als"
|
||||
},
|
||||
{
|
||||
"hash": "e6daf889df9686d9e2f99387e6226fd7",
|
||||
"projectName": "ai-hola-buenas-1764558274015.als",
|
||||
"meta": {
|
||||
"creator": "Ableton Live 12.2",
|
||||
"version": "5.12.0_12203",
|
||||
"revision": "1c7a2c5dacd710ba28150f2c1534c22b1c158263",
|
||||
"fileName": "ai-hola-buenas-1764558274015.als",
|
||||
"sizeBytes": 6665466,
|
||||
"sizeHuman": "6.4 MB"
|
||||
},
|
||||
"liveSet": {
|
||||
"tempo": 124,
|
||||
"loopLengthBeats": 272,
|
||||
"durationSeconds": 131.61290322580646,
|
||||
"durationHuman": "2:12",
|
||||
"loopStart": 0,
|
||||
"scenes": []
|
||||
},
|
||||
"tracks": [
|
||||
{
|
||||
"name": "hola 1",
|
||||
"type": "Audio",
|
||||
"deviceCount": 3,
|
||||
"color": "22"
|
||||
},
|
||||
{
|
||||
"name": "buenas 2",
|
||||
"type": "Audio",
|
||||
"deviceCount": 0,
|
||||
"color": "22"
|
||||
},
|
||||
{
|
||||
"name": "Track 3",
|
||||
"type": "Audio",
|
||||
"deviceCount": 1,
|
||||
"color": "22"
|
||||
},
|
||||
{
|
||||
"name": "Track 4",
|
||||
"type": "Audio",
|
||||
"deviceCount": 2,
|
||||
"color": "22"
|
||||
},
|
||||
{
|
||||
"name": "Track 5",
|
||||
"type": "Audio",
|
||||
"deviceCount": 1,
|
||||
"color": "22"
|
||||
},
|
||||
{
|
||||
"name": "Track 6",
|
||||
"type": "MIDI",
|
||||
"deviceCount": 1,
|
||||
"color": "22"
|
||||
},
|
||||
{
|
||||
"name": "Track 7",
|
||||
"type": "MIDI",
|
||||
"deviceCount": 4,
|
||||
"color": "22"
|
||||
},
|
||||
{
|
||||
"name": "Track 8",
|
||||
"type": "MIDI",
|
||||
"deviceCount": 2,
|
||||
"color": "22"
|
||||
},
|
||||
{
|
||||
"name": "Track 9",
|
||||
"type": "MIDI",
|
||||
"deviceCount": 3,
|
||||
"color": "22"
|
||||
},
|
||||
{
|
||||
"name": "Track 10",
|
||||
"type": "MIDI",
|
||||
"deviceCount": 2,
|
||||
"color": "22"
|
||||
},
|
||||
{
|
||||
"name": "Track 11",
|
||||
"type": "MIDI",
|
||||
"deviceCount": 2,
|
||||
"color": "22"
|
||||
},
|
||||
{
|
||||
"name": "Track 12",
|
||||
"type": "MIDI",
|
||||
"deviceCount": 3,
|
||||
"color": "22"
|
||||
},
|
||||
{
|
||||
"name": "Track 13",
|
||||
"type": "MIDI",
|
||||
"deviceCount": 3,
|
||||
"color": "22"
|
||||
},
|
||||
{
|
||||
"name": "Track 14",
|
||||
"type": "MIDI",
|
||||
"deviceCount": 3,
|
||||
"color": "22"
|
||||
},
|
||||
{
|
||||
"name": "Track 15",
|
||||
"type": "MIDI",
|
||||
"deviceCount": 5,
|
||||
"color": "22"
|
||||
},
|
||||
{
|
||||
"name": "Track 16",
|
||||
"type": "MIDI",
|
||||
"deviceCount": 2,
|
||||
"color": "22"
|
||||
},
|
||||
{
|
||||
"name": "Track 17",
|
||||
"type": "Grupo",
|
||||
"deviceCount": 1,
|
||||
"color": "22"
|
||||
},
|
||||
{
|
||||
"name": "Track 18",
|
||||
"type": "Grupo",
|
||||
"deviceCount": 3,
|
||||
"color": "22"
|
||||
},
|
||||
{
|
||||
"name": "Track 19",
|
||||
"type": "Grupo",
|
||||
"deviceCount": 1,
|
||||
"color": "22"
|
||||
}
|
||||
],
|
||||
"stats": {
|
||||
"audio": 5,
|
||||
"midi": 11,
|
||||
"group": 3,
|
||||
"totalTracks": 19,
|
||||
"devices": 42,
|
||||
"scenes": 0,
|
||||
"samples": 8
|
||||
},
|
||||
"samples": {
|
||||
"total": 8,
|
||||
"relative": [
|
||||
"Samples/Imported/RUFUS DU SOL - In the Moment (Adriatique Remix) Acapella.mp3",
|
||||
"Samples/Processed/Bounce/Bounce KICK #1 [2025-08-30 144250]-3.wav",
|
||||
"Samples/Recorded/12-Audio 0001 [2025-08-30 143952].wav",
|
||||
"Presets/Audio Effects/Audio Effect Rack/Filter HI and Low.adg",
|
||||
"Samples/Recorded/12-Audio 0001 [2025-08-30 144108].wav",
|
||||
"Samples/Imported/Clap Fx.wav",
|
||||
"Samples/Imported/Clap.wav",
|
||||
"Swing and Groove/Swing/Swing 16-99.agr"
|
||||
],
|
||||
"absolute": [
|
||||
"C:/Users/novik/Desktop/YOUTUBE RUFUS DUU SOL & ARTBAT/GHOSTPRODUCTION.PRO (ABLETON LIVE) (Style RUFUS DUU SOL) Project/Samples/Imported/RUFUS DU SOL - In the Moment (Adriatique Remix) Acapella.mp3",
|
||||
"C:/VST2/Proximity-x64.dll",
|
||||
"C:/Users/novik/Desktop/YOUTUBE RUFUS DUU SOL & ARTBAT/GHOSTPRODUCTION.PRO (ABLETON LIVE) (Style RUFUS DUU SOL) Project/Samples/Processed/Bounce/Bounce KICK #1 [2025-08-30 144250]-3.wav",
|
||||
"C:/Users/novik/Desktop/YOUTUBE RUFUS DUU SOL & ARTBAT/GHOSTPRODUCTION.PRO (ABLETON LIVE) (Style RUFUS DUU SOL) Project/Samples/Recorded/12-Audio 0001 [2025-08-30 143952].wav",
|
||||
"C:/Users/novik/OneDrive/Documenten/Ableton/User Library/Presets/Audio Effects/Audio Effect Rack/Filter HI and Low.adg",
|
||||
"C:/Users/novik/Desktop/YOUTUBE RUFUS DUU SOL & ARTBAT/GHOSTPRODUCTION.PRO (ABLETON LIVE) (Style RUFUS DUU SOL) Project/Samples/Recorded/12-Audio 0001 [2025-08-30 144108].wav",
|
||||
"C:/VST2/Fabfilter/FabFilter Pro-Q 4.dll",
|
||||
"C:/Users/novik/Desktop/YOUTUBE RUFUS DUU SOL & ARTBAT/GHOSTPRODUCTION.PRO (ABLETON LIVE) (Style RUFUS DUU SOL) Project/Samples/Imported/Clap Fx.wav",
|
||||
"C:/Users/novik/Desktop/YOUTUBE RUFUS DUU SOL & ARTBAT/GHOSTPRODUCTION.PRO (ABLETON LIVE) (Style RUFUS DUU SOL) Project/Samples/Imported/Clap.wav",
|
||||
"C:/VST2/Fabfilter/FabFilter Pro-C 2.dll"
|
||||
]
|
||||
},
|
||||
"storedAt": "2025-12-01T03:04:35.766Z",
|
||||
"filePath": "library/e6daf889df9686d9e2f99387e6226fd7.als"
|
||||
},
|
||||
{
|
||||
"hash": "4f6a02d3a9826f59ab7c06f6a622005a",
|
||||
"projectName": "ai-generame-un-als-techno-1764558411120.als",
|
||||
"meta": {
|
||||
"creator": "Ableton Live 12.2",
|
||||
"version": "5.12.0_12203",
|
||||
"revision": "1c7a2c5dacd710ba28150f2c1534c22b1c158263",
|
||||
"fileName": "ai-generame-un-als-techno-1764558411120.als",
|
||||
"sizeBytes": 6666252,
|
||||
"sizeHuman": "6.4 MB"
|
||||
},
|
||||
"liveSet": {
|
||||
"tempo": 124,
|
||||
"loopLengthBeats": 272,
|
||||
"durationSeconds": 131.61290322580646,
|
||||
"durationHuman": "2:12",
|
||||
"loopStart": 0,
|
||||
"scenes": []
|
||||
},
|
||||
"tracks": [
|
||||
{
|
||||
"name": "generame 1",
|
||||
"type": "Audio",
|
||||
"deviceCount": 3,
|
||||
"color": "22"
|
||||
},
|
||||
{
|
||||
"name": "un 2",
|
||||
"type": "Audio",
|
||||
"deviceCount": 0,
|
||||
"color": "22"
|
||||
},
|
||||
{
|
||||
"name": "als 3",
|
||||
"type": "Audio",
|
||||
"deviceCount": 1,
|
||||
"color": "22"
|
||||
},
|
||||
{
|
||||
"name": "techno 4",
|
||||
"type": "Audio",
|
||||
"deviceCount": 2,
|
||||
"color": "22"
|
||||
},
|
||||
{
|
||||
"name": "Track 5",
|
||||
"type": "Audio",
|
||||
"deviceCount": 1,
|
||||
"color": "22"
|
||||
},
|
||||
{
|
||||
"name": "Track 6",
|
||||
"type": "MIDI",
|
||||
"deviceCount": 1,
|
||||
"color": "22"
|
||||
},
|
||||
{
|
||||
"name": "Track 7",
|
||||
"type": "MIDI",
|
||||
"deviceCount": 4,
|
||||
"color": "22"
|
||||
},
|
||||
{
|
||||
"name": "Track 8",
|
||||
"type": "MIDI",
|
||||
"deviceCount": 2,
|
||||
"color": "22"
|
||||
},
|
||||
{
|
||||
"name": "Track 9",
|
||||
"type": "MIDI",
|
||||
"deviceCount": 3,
|
||||
"color": "22"
|
||||
},
|
||||
{
|
||||
"name": "Track 10",
|
||||
"type": "MIDI",
|
||||
"deviceCount": 2,
|
||||
"color": "22"
|
||||
},
|
||||
{
|
||||
"name": "Track 11",
|
||||
"type": "MIDI",
|
||||
"deviceCount": 2,
|
||||
"color": "22"
|
||||
},
|
||||
{
|
||||
"name": "Track 12",
|
||||
"type": "MIDI",
|
||||
"deviceCount": 3,
|
||||
"color": "22"
|
||||
},
|
||||
{
|
||||
"name": "Track 13",
|
||||
"type": "MIDI",
|
||||
"deviceCount": 3,
|
||||
"color": "22"
|
||||
},
|
||||
{
|
||||
"name": "Track 14",
|
||||
"type": "MIDI",
|
||||
"deviceCount": 3,
|
||||
"color": "22"
|
||||
},
|
||||
{
|
||||
"name": "Track 15",
|
||||
"type": "MIDI",
|
||||
"deviceCount": 5,
|
||||
"color": "22"
|
||||
},
|
||||
{
|
||||
"name": "Track 16",
|
||||
"type": "MIDI",
|
||||
"deviceCount": 2,
|
||||
"color": "22"
|
||||
},
|
||||
{
|
||||
"name": "Track 17",
|
||||
"type": "Grupo",
|
||||
"deviceCount": 1,
|
||||
"color": "22"
|
||||
},
|
||||
{
|
||||
"name": "Track 18",
|
||||
"type": "Grupo",
|
||||
"deviceCount": 3,
|
||||
"color": "22"
|
||||
},
|
||||
{
|
||||
"name": "Track 19",
|
||||
"type": "Grupo",
|
||||
"deviceCount": 1,
|
||||
"color": "22"
|
||||
}
|
||||
],
|
||||
"stats": {
|
||||
"audio": 5,
|
||||
"midi": 11,
|
||||
"group": 3,
|
||||
"totalTracks": 19,
|
||||
"devices": 42,
|
||||
"scenes": 0,
|
||||
"samples": 8
|
||||
},
|
||||
"samples": {
|
||||
"total": 8,
|
||||
"relative": [
|
||||
"Samples/Imported/RUFUS DU SOL - In the Moment (Adriatique Remix) Acapella.mp3",
|
||||
"Samples/Processed/Bounce/Bounce KICK #1 [2025-08-30 144250]-3.wav",
|
||||
"Samples/Recorded/12-Audio 0001 [2025-08-30 143952].wav",
|
||||
"Presets/Audio Effects/Audio Effect Rack/Filter HI and Low.adg",
|
||||
"Samples/Recorded/12-Audio 0001 [2025-08-30 144108].wav",
|
||||
"Samples/Imported/Clap Fx.wav",
|
||||
"Samples/Imported/Clap.wav",
|
||||
"Swing and Groove/Swing/Swing 16-99.agr"
|
||||
],
|
||||
"absolute": [
|
||||
"C:/Users/novik/Desktop/YOUTUBE RUFUS DUU SOL & ARTBAT/GHOSTPRODUCTION.PRO (ABLETON LIVE) (Style RUFUS DUU SOL) Project/Samples/Imported/RUFUS DU SOL - In the Moment (Adriatique Remix) Acapella.mp3",
|
||||
"C:/VST2/Proximity-x64.dll",
|
||||
"C:/Users/novik/Desktop/YOUTUBE RUFUS DUU SOL & ARTBAT/GHOSTPRODUCTION.PRO (ABLETON LIVE) (Style RUFUS DUU SOL) Project/Samples/Processed/Bounce/Bounce KICK #1 [2025-08-30 144250]-3.wav",
|
||||
"C:/Users/novik/Desktop/YOUTUBE RUFUS DUU SOL & ARTBAT/GHOSTPRODUCTION.PRO (ABLETON LIVE) (Style RUFUS DUU SOL) Project/Samples/Recorded/12-Audio 0001 [2025-08-30 143952].wav",
|
||||
"C:/Users/novik/OneDrive/Documenten/Ableton/User Library/Presets/Audio Effects/Audio Effect Rack/Filter HI and Low.adg",
|
||||
"C:/Users/novik/Desktop/YOUTUBE RUFUS DUU SOL & ARTBAT/GHOSTPRODUCTION.PRO (ABLETON LIVE) (Style RUFUS DUU SOL) Project/Samples/Recorded/12-Audio 0001 [2025-08-30 144108].wav",
|
||||
"C:/VST2/Fabfilter/FabFilter Pro-Q 4.dll",
|
||||
"C:/Users/novik/Desktop/YOUTUBE RUFUS DUU SOL & ARTBAT/GHOSTPRODUCTION.PRO (ABLETON LIVE) (Style RUFUS DUU SOL) Project/Samples/Imported/Clap Fx.wav",
|
||||
"C:/Users/novik/Desktop/YOUTUBE RUFUS DUU SOL & ARTBAT/GHOSTPRODUCTION.PRO (ABLETON LIVE) (Style RUFUS DUU SOL) Project/Samples/Imported/Clap.wav",
|
||||
"C:/VST2/Fabfilter/FabFilter Pro-C 2.dll"
|
||||
]
|
||||
},
|
||||
"storedAt": "2025-12-01T03:06:52.832Z",
|
||||
"filePath": "library/4f6a02d3a9826f59ab7c06f6a622005a.als"
|
||||
}
|
||||
]
|
||||
@@ -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": "",
|
||||
|
||||
@@ -46,7 +46,7 @@ function readLibrary() {
|
||||
}
|
||||
}
|
||||
|
||||
function listSources() {
|
||||
function scanSources() {
|
||||
const result = [];
|
||||
if (!fs.existsSync(SOURCES_DIR)) {
|
||||
return result;
|
||||
@@ -282,7 +282,7 @@ async function generateFromPrompt(prompt, options = {}) {
|
||||
if (!library.length) {
|
||||
throw new Error('No hay ALS en la biblioteca. Sube al menos uno antes de generar.');
|
||||
}
|
||||
const sources = listSources();
|
||||
const sources = scanSources();
|
||||
const tokens = prompt
|
||||
.toLowerCase()
|
||||
.split(/[^a-z0-9]+/)
|
||||
@@ -341,5 +341,13 @@ async function generateFromPrompt(prompt, options = {}) {
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
generateFromPrompt
|
||||
generateFromPrompt,
|
||||
listLibrary: () => {
|
||||
ensureDirs();
|
||||
return readLibrary();
|
||||
},
|
||||
listSources: () => {
|
||||
ensureDirs();
|
||||
return scanSources();
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user