fivetech commited on
Commit
61e5e63
·
verified ·
1 Parent(s): 2448214

Update core/commands.mjs

Browse files
Files changed (1) hide show
  1. 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(){