Spaces:
Running
Running
File size: 4,627 Bytes
b30b7c5 6b45f01 b30b7c5 6b45f01 b30b7c5 6b45f01 b30b7c5 6b45f01 b30b7c5 6b45f01 b30b7c5 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | // Frase legible por humano para una tool-call («leyendo app.js…»). Compartido
// por el cerebro CEO (ceo.js) y el streaming en vivo del chat — así nunca se
// le enseña JSON crudo al usuario, siempre la misma redacción. Cubre los
// nombres de herramienta de Elffuss Code (code.*, terminal.*) y de Elffuss
// Claw (fs.*, app.*, web.*, skill.*, memory.*, tasks.*) — un tool desconocido
// cae al genérico «nombre argumento» sin romper nada.
//
// Localizado: ES por defecto (usuarios españoles intactos), EN de fallback.
// Autocontenido a propósito — este fichero es IDÉNTICO en Code y en Claw, y
// Code no tiene i18n.js, así que la tabla de idioma vive aquí.
const HL = {
es: {
read: p => `leyendo ${p}…`, write: p => `escribiendo ${p}…`,
tree: p => `explorando ${p || 'el proyecto'}…`, list: p => `explorando ${p || 'la carpeta'}…`,
search: q => `buscando «${q}»…`, pick: () => 'pidiendo acceso a una carpeta…',
copy: x => `copiando ${x || 'archivos'}…`, watch: x => `vigilando ${x || 'una carpeta'}…`,
run: c => `ejecutando: ${c}`,
appCreate: n => `creando la app «${n}»…`, appOpen: n => `abriendo la app «${n}»…`,
skillCreate: n => `creando la skill «${n}»…`, memSave: f => `recordando: ${f}…`,
taskAdd: () => 'programando una tarea…',
webSearch: q => `buscando en internet «${q}»…`, webImages: q => `buscando imágenes de «${q}»…`,
webFetch: u => `leyendo ${u}…`, prep: 'preparando una acción…',
},
en: {
read: p => `reading ${p}…`, write: p => `writing ${p}…`,
tree: p => `exploring ${p || 'the project'}…`, list: p => `exploring ${p || 'the folder'}…`,
search: q => `searching “${q}”…`, pick: () => 'requesting folder access…',
copy: x => `copying ${x || 'files'}…`, watch: x => `watching ${x || 'a folder'}…`,
run: c => `running: ${c}`,
appCreate: n => `creating the app “${n}”…`, appOpen: n => `opening the app “${n}”…`,
skillCreate: n => `creating the skill “${n}”…`, memSave: f => `remembering: ${f}…`,
taskAdd: () => 'scheduling a task…',
webSearch: q => `searching the web for “${q}”…`, webImages: q => `searching images of “${q}”…`,
webFetch: u => `reading ${u}…`, prep: 'preparing an action…',
},
};
function hl() { return HL[(navigator.language || 'es').slice(0, 2).toLowerCase()] || HL.en; }
export function humanizeTool(name, args) {
const p = args?.path, q = args?.query, c = args?.command, n = args?.name;
const t = hl();
switch (name) {
case 'code.read': case 'fs.read': return t.read(p);
case 'code.write': case 'fs.write': return t.write(p);
case 'code.tree': return t.tree(p);
case 'fs.list': return t.list(p);
case 'code.search': return t.search(q);
case 'fs.pick_folder': return t.pick();
case 'fs.copy': return t.copy(args?.pattern);
case 'fs.watch': return t.watch(args?.from);
case 'terminal.run': return t.run(c);
case 'app.create': return t.appCreate(n);
case 'app.open': return t.appOpen(n);
case 'skill.create': return t.skillCreate(n);
case 'memory.save': return t.memSave(args?.fact);
case 'tasks.add': return t.taskAdd();
case 'web.search': return t.webSearch(q);
case 'web.images': return t.webImages(q);
case 'web.fetch': return t.webFetch(p || args?.url);
default: return name + (p || q || c || n ? ' ' + (p || q || c || n) : '');
}
}
// Detecta si el buffer que va llegando EN STREAMING ha entrado en un bloque de
// tool-call (```tool { … }) y, si es así, devuelve una frase humana en vez del
// JSON crudo — «preparando una acción…» hasta que el nombre de la tool sea
// legible, luego «leyendo app.js…» tan pronto como el campo aparezca, aunque
// el JSON todavía no haya cerrado.
export function humanizeStreamPreview(buf) {
if (buf.search(/```/) === -1 && !/^\s*\{\s*"tool"/.test(buf)) return null;
const toolM = buf.match(/"tool"\s*:\s*"([\w.]+)"/);
if (!toolM) return hl().prep;
const pathM = buf.match(/"path"\s*:\s*"((?:[^"\\]|\\.)*)"/);
const queryM = buf.match(/"query"\s*:\s*"((?:[^"\\]|\\.)*)"/);
const cmdM = buf.match(/"command"\s*:\s*"((?:[^"\\]|\\.)*)"/);
const nameM = buf.match(/"name"\s*:\s*"((?:[^"\\]|\\.)*)"/);
const out = humanizeTool(toolM[1], { path: pathM?.[1], query: queryM?.[1], command: cmdM?.[1], name: nameM?.[1] });
// el nombre de la tool ya se ve pero su campo (path/query/…) aún no llegó:
// mejor el genérico que un «leyendo undefined…» a medio streamear
return /undefined/.test(out) ? hl().prep : out;
}
|