Spaces:
Running
Running
Update core/commands.mjs
Browse files- core/commands.mjs +17 -1
core/commands.mjs
CHANGED
|
@@ -4,6 +4,20 @@ const APCorePrompts = {
|
|
| 4 |
GAMMA: 'Eres GAMMA, agente de proveedores de FiveTech. Responde en español solo con hechos de los datos vigentes del contexto: compara proveedores, plazos y costes y señala el proveedor que corresponda. Nunca prometas entregas ni envíos que no consten, ni digas que has comprado ni recibido mercancía. No atribuyas acciones a ALPHA o BETA si no constan en la auditoría. No crees propuestas ni usas herramientas: la propuesta la crea ALPHA con el proveedor seleccionado. No reveles proveedores de modelos.',
|
| 5 |
};
|
| 6 |
export const APCommands = {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7 |
async reset(){if(!await AP.confirmAction('Restablecer solo esta demo','Esto borra permanentemente pedidos, propuestas, decisiones, perfiles y movimientos locales de este navegador y vuelve a cargar el escenario ficticio de julio de 2030. No afecta otros equipos ni sistemas reales.'))return;await new Promise((resolve,reject)=>{const t=AP.store.transaction('database','readwrite');t.objectStore('database').delete('main');t.oncomplete=resolve;t.onerror=()=>reject(t.error);});AP.db?.close();AP.db=null;localStorage.removeItem('adaptapro-notices-read');await AP.init();AP.audit('SISTEMA','demo_restablecida','settings','reset',{origen:'boton_menu'});await AP.persist();AP.note('Datos locales restablecidos.');},
|
| 8 |
async decide(id,status){
|
| 9 |
const p=AP.one('SELECT * FROM purchase_proposals WHERE id=?',[id]);if(!p)return;
|
|
@@ -54,10 +68,12 @@ export const APCommands = {
|
|
| 54 |
const ctx=AP.context(who);const req=String(text);
|
| 55 |
if(/producci|fabricaci|materiales|taller/i.test(req))ctx.production=AP.query('SELECT * FROM production_jobs ORDER BY due_at');
|
| 56 |
if(/planific|tareas|prioridad|calendario|programaci/i.test(req))ctx.planning=AP.query('SELECT * FROM planning_tasks ORDER BY due_at');
|
|
|
|
|
|
|
| 57 |
const messages=[{role:'system',content:APCorePrompts[who]},{role:'user',content:'Modo actual: '+AP.mode+'. Datos vigentes: '+JSON.stringify(ctx)+'\nSolicitud: '+text}];
|
| 58 |
let m=await AP.modelCall(messages,who==='ALPHA'?tools:undefined);
|
| 59 |
if(who==='ALPHA'&&m.tool_calls?.length){messages.push(m);for(const c of m.tool_calls.slice(0,2)){let result;try{if(c.function.name!=='proponer_reposicion')throw Error('Herramienta no admitida');result=await AP.command({cmd:'propuesta_crear',payload:JSON.parse(c.function.arguments),actor:who});}catch(e){result='Error: '+e.message;}messages.push({role:'tool',tool_call_id:c.id,content:result});}m=await AP.modelCall(messages);}
|
| 60 |
-
if(!quiet)AP.append(m.content||'No hubo respuesta del agente.','ai');AP.audit(who,'analisis_completado','agent',who,{model:AP.activeModel||AP.model});if(!quiet)AP.audit(who,'respuesta_modelo','chat',who,{text:String(m.content||'').slice(0,500)});await AP.persist();AP.render();AP.setAgentState(st,'Disponible',false);AP.note('Análisis finalizado · '+AP.query("SELECT count(*) AS n FROM approval_queue WHERE status='pendiente'")[0].n+' pendientes');
|
| 61 |
}catch(e){if(!quiet)AP.append('No se pudo contactar al agente. Tus datos y propuestas locales siguen disponibles.','ai');if(!quiet)AP.audit(who,'chat_sin_respuesta','chat',who,{error:String(e&&e.message||e).slice(0,200)});AP.setAgentState(st,'Sin respuesta',false);AP.note('Agente no disponible: '+e.message,true);}finally{AP.busy=false;}
|
| 62 |
},
|
| 63 |
async cycle(){
|
|
|
|
| 4 |
GAMMA: 'Eres GAMMA, agente de proveedores de FiveTech. Responde en español solo con hechos de los datos vigentes del contexto: compara proveedores, plazos y costes y señala el proveedor que corresponda. Nunca prometas entregas ni envíos que no consten, ni digas que has comprado ni recibido mercancía. No atribuyas acciones a ALPHA o BETA si no constan en la auditoría. No crees propuestas ni usas herramientas: la propuesta la crea ALPHA con el proveedor seleccionado. No reveles proveedores de modelos.',
|
| 5 |
};
|
| 6 |
export const APCommands = {
|
| 7 |
+
async webSearch(topic){
|
| 8 |
+
const q=String(topic).slice(0,300).replace(/\s+/g,' ').trim();
|
| 9 |
+
if(!q)throw new Error('consulta vacía');
|
| 10 |
+
try{
|
| 11 |
+
const r=await fetch('https://api.tavily.com/search',{method:'POST',headers:{'Content-Type':'application/json','X-Tavily-Access-Mode':'keyless'},body:JSON.stringify({query:q,max_results:4,search_depth:'basic'})});
|
| 12 |
+
if(r.ok){const j=await r.json();const items=(j.results||[]).slice(0,4).map(x=>({title:String(x.title||'').slice(0,140),url:String(x.url||''),snippet:String(x.content||'').slice(0,240)})).filter(x=>x.url);if(items.length)return items;}
|
| 13 |
+
if(r.status===429)throw new Error('límite de consultas gratuitas alcanzado; inténtalo más tarde');
|
| 14 |
+
}catch(e){if(String(e&&e.message||'').startsWith('límite'))throw e;}
|
| 15 |
+
const w=await fetch('https://es.wikipedia.org/w/api.php?action=opensearch&search='+encodeURIComponent(q)+'&limit=3&namespace=0&format=json&origin=*');
|
| 16 |
+
if(!w.ok)throw new Error('wikipedia '+w.status);
|
| 17 |
+
const wj=await w.json();const items=(wj[1]||[]).map((t,i)=>({title:String(t),url:String((wj[3]||[])[i]||''),snippet:''})).filter(x=>x.url);
|
| 18 |
+
if(!items.length)throw new Error('sin resultados');
|
| 19 |
+
return items;
|
| 20 |
+
},
|
| 21 |
async reset(){if(!await AP.confirmAction('Restablecer solo esta demo','Esto borra permanentemente pedidos, propuestas, decisiones, perfiles y movimientos locales de este navegador y vuelve a cargar el escenario ficticio de julio de 2030. No afecta otros equipos ni sistemas reales.'))return;await new Promise((resolve,reject)=>{const t=AP.store.transaction('database','readwrite');t.objectStore('database').delete('main');t.oncomplete=resolve;t.onerror=()=>reject(t.error);});AP.db?.close();AP.db=null;localStorage.removeItem('adaptapro-notices-read');await AP.init();AP.audit('SISTEMA','demo_restablecida','settings','reset',{origen:'boton_menu'});await AP.persist();AP.note('Datos locales restablecidos.');},
|
| 22 |
async decide(id,status){
|
| 23 |
const p=AP.one('SELECT * FROM purchase_proposals WHERE id=?',[id]);if(!p)return;
|
|
|
|
| 68 |
const ctx=AP.context(who);const req=String(text);
|
| 69 |
if(/producci|fabricaci|materiales|taller/i.test(req))ctx.production=AP.query('SELECT * FROM production_jobs ORDER BY due_at');
|
| 70 |
if(/planific|tareas|prioridad|calendario|programaci/i.test(req))ctx.planning=AP.query('SELECT * FROM planning_tasks ORDER BY due_at');
|
| 71 |
+
let webSources='';
|
| 72 |
+
if(!quiet){AP.append('🔎 Buscando contexto web…','ai');try{const web=await APCommands.webSearch(req);ctx.web=web;webSources=web.map(x=>'· '+x.title+' · '+x.url).join('\n');}catch(e){webSources='Búsqueda web no disponible: '+String(e&&e.message||e).slice(0,140)+'. La respuesta se basa solo en los datos locales.';}}
|
| 73 |
const messages=[{role:'system',content:APCorePrompts[who]},{role:'user',content:'Modo actual: '+AP.mode+'. Datos vigentes: '+JSON.stringify(ctx)+'\nSolicitud: '+text}];
|
| 74 |
let m=await AP.modelCall(messages,who==='ALPHA'?tools:undefined);
|
| 75 |
if(who==='ALPHA'&&m.tool_calls?.length){messages.push(m);for(const c of m.tool_calls.slice(0,2)){let result;try{if(c.function.name!=='proponer_reposicion')throw Error('Herramienta no admitida');result=await AP.command({cmd:'propuesta_crear',payload:JSON.parse(c.function.arguments),actor:who});}catch(e){result='Error: '+e.message;}messages.push({role:'tool',tool_call_id:c.id,content:result});}m=await AP.modelCall(messages);}
|
| 76 |
+
if(!quiet){AP.append(m.content||'No hubo respuesta del agente.','ai');AP.append('📚 Fuentes\n'+webSources,'ai');}AP.audit(who,'analisis_completado','agent',who,{model:AP.activeModel||AP.model});if(!quiet)AP.audit(who,'respuesta_modelo','chat',who,{text:String(m.content||'').slice(0,500)});await AP.persist();AP.render();AP.setAgentState(st,'Disponible',false);AP.note('Análisis finalizado · '+AP.query("SELECT count(*) AS n FROM approval_queue WHERE status='pendiente'")[0].n+' pendientes');
|
| 77 |
}catch(e){if(!quiet)AP.append('No se pudo contactar al agente. Tus datos y propuestas locales siguen disponibles.','ai');if(!quiet)AP.audit(who,'chat_sin_respuesta','chat',who,{error:String(e&&e.message||e).slice(0,200)});AP.setAgentState(st,'Sin respuesta',false);AP.note('Agente no disponible: '+e.message,true);}finally{AP.busy=false;}
|
| 78 |
},
|
| 79 |
async cycle(){
|