xonecode 0.8.42 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/apps/web/dist/assets/{index-CwAAn-xT.css → index-CtfT1BjI.css} +1 -1
- package/apps/web/dist/assets/{index--HvR4hMi.js → index-DqcZ7_Rx.js} +68 -68
- package/apps/web/dist/assets/{php-HCmCEpFP.js → php-DjRQ1K-w.js} +1 -1
- package/apps/web/dist/assets/{ruby-DsWetjbK.js → ruby-BcLyZ3qi.js} +1 -1
- package/apps/web/dist/index.html +2 -2
- package/dist/agent/config/settingsEnDisco.js +50 -2
- package/dist/agent/config/settingsEnDisco.js.map +1 -1
- package/dist/agent/grafo/arbolDeProyecto.js +1 -1
- package/dist/agent/grafo/arbolDeProyecto.js.map +1 -1
- package/dist/agent/grafo/opcionesDeFicheros.js +24 -0
- package/dist/agent/grafo/opcionesDeFicheros.js.map +1 -0
- package/dist/agent/grafo/perfiles.js +1 -1
- package/dist/agent/grafo/perfiles.js.map +1 -1
- package/dist/agent/grafo/proyecto.js +5 -1
- package/dist/agent/grafo/proyecto.js.map +1 -1
- package/dist/agent/grafo/xoneAgent.js +49 -51
- package/dist/agent/grafo/xoneAgent.js.map +1 -1
- package/dist/agent/motores/trueforge/capacidades.js +138 -0
- package/dist/agent/motores/trueforge/capacidades.js.map +1 -0
- package/dist/agent/motores/trueforge/eventosTrueforge.js +98 -0
- package/dist/agent/motores/trueforge/eventosTrueforge.js.map +1 -0
- package/dist/agent/motores/trueforge/memoriaTrueforge.js +336 -0
- package/dist/agent/motores/trueforge/memoriaTrueforge.js.map +1 -0
- package/dist/agent/motores/trueforge/metricasTrueforge.js +55 -0
- package/dist/agent/motores/trueforge/metricasTrueforge.js.map +1 -0
- package/dist/agent/motores/trueforge/modeloExterno.js +46 -0
- package/dist/agent/motores/trueforge/modeloExterno.js.map +1 -0
- package/dist/agent/motores/trueforge/modeloLangchain.js +149 -0
- package/dist/agent/motores/trueforge/modeloLangchain.js.map +1 -0
- package/dist/agent/motores/trueforge/recortes.js +121 -0
- package/dist/agent/motores/trueforge/recortes.js.map +1 -0
- package/dist/agent/motores/trueforge/sesionTrueforge.js +1045 -0
- package/dist/agent/motores/trueforge/sesionTrueforge.js.map +1 -0
- package/dist/agent/motores/trueforge/skillsTrueforge.js +14 -0
- package/dist/agent/motores/trueforge/skillsTrueforge.js.map +1 -0
- package/dist/agent/motores/trueforge/toolsDeFichero.js +264 -0
- package/dist/agent/motores/trueforge/toolsDeFichero.js.map +1 -0
- package/dist/agent/motores/trueforge/toolsPropias.js +65 -0
- package/dist/agent/motores/trueforge/toolsPropias.js.map +1 -0
- package/dist/agent/motores/trueforge/trueforge.js +45 -0
- package/dist/agent/motores/trueforge/trueforge.js.map +1 -0
- package/dist/agent/sesiones/memoriaDeHilo.js +24 -0
- package/dist/agent/sesiones/memoriaDeHilo.js.map +1 -0
- package/dist/agent/subagentes/actividadDeCodex.js +60 -0
- package/dist/agent/subagentes/actividadDeCodex.js.map +1 -0
- package/dist/agent/subagentes/agentesEnDisco.js +4 -0
- package/dist/agent/subagentes/agentesEnDisco.js.map +1 -1
- package/dist/agent/subagentes/escrituraExterna.js +2 -0
- package/dist/agent/subagentes/escrituraExterna.js.map +1 -1
- package/dist/agent/subagentes/subagenteCodex.js +20 -0
- package/dist/agent/subagentes/subagenteCodex.js.map +1 -1
- package/dist/agent/subagentes/subagenteExterno.js +269 -202
- package/dist/agent/subagentes/subagenteExterno.js.map +1 -1
- package/dist/agent/subagentes/subagenteOpencode.js +18 -1
- package/dist/agent/subagentes/subagenteOpencode.js.map +1 -1
- package/dist/agent/turno/diagnosticoDeTools.js +3 -0
- package/dist/agent/turno/diagnosticoDeTools.js.map +1 -1
- package/dist/agent/turno/ficherosDelProyecto.js +62 -0
- package/dist/agent/turno/ficherosDelProyecto.js.map +1 -0
- package/dist/agent/turno/informeDeTraza.js +28 -1
- package/dist/agent/turno/informeDeTraza.js.map +1 -1
- package/dist/agent/turno/resumenDeTool.js +3 -0
- package/dist/agent/turno/resumenDeTool.js.map +1 -1
- package/dist/agent/turno/sesionReal.js +2 -0
- package/dist/agent/turno/sesionReal.js.map +1 -0
- package/dist/agent/turno/turnoReal.js +40 -163
- package/dist/agent/turno/turnoReal.js.map +1 -1
- package/dist/agent/turno/verificacion.js +142 -0
- package/dist/agent/turno/verificacion.js.map +1 -0
- package/dist/cli/config.js +19 -0
- package/dist/cli/config.js.map +1 -1
- package/dist/cli/consola.js.map +1 -1
- package/dist/cli/main.js +52 -3
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/tui/correrTui.js +1 -1
- package/dist/cli/tui/correrTui.js.map +1 -1
- package/dist/cli/tui/transcript.js +5 -0
- package/dist/cli/tui/transcript.js.map +1 -1
- package/dist/core/actos.js.map +1 -1
- package/dist/core/config.js +13 -0
- package/dist/core/config.js.map +1 -1
- package/dist/core/dispositivoDeSesion.js +49 -0
- package/dist/core/dispositivoDeSesion.js.map +1 -0
- package/dist/core/motor.js +41 -0
- package/dist/core/motor.js.map +1 -0
- package/dist/core/ports.js.map +1 -1
- package/dist/core/settings.js +21 -0
- package/dist/core/settings.js.map +1 -1
- package/dist/core/shellDeAgente.js +3 -0
- package/dist/core/shellDeAgente.js.map +1 -1
- package/dist/core/trazaDeErrores.js +8 -2
- package/dist/core/trazaDeErrores.js.map +1 -1
- package/dist/core/turno.js +10 -0
- package/dist/core/turno.js.map +1 -1
- package/dist/web/servidor/arranque.js +96 -8
- package/dist/web/servidor/arranque.js.map +1 -1
- package/dist/web/servidor/pielWeb.js +6 -0
- package/dist/web/servidor/pielWeb.js.map +1 -1
- package/dist/web/servidor/sesiones.js +11 -0
- package/dist/web/servidor/sesiones.js.map +1 -1
- package/dist/web/servidor/transporte.js.map +1 -1
- package/dist/web/servidor/vestibulo.js +83 -8
- package/dist/web/servidor/vestibulo.js.map +1 -1
- package/package.json +7 -2
- package/skills/xone-hotswap/SKILL.md +5 -1
- package/skills/xone-hotswap/lib/dispositivo.mjs +72 -0
- package/skills/xone-hotswap/scripts/xone-arrancar-ios +3 -1
- package/skills/xone-hotswap/scripts/xone-captura-android +5 -1
- package/skills/xone-hotswap/scripts/xone-desplegar-android +5 -1
- package/skills/xone-hotswap/scripts/xone-log-android +5 -1
- package/skills/xone-hotswap/scripts/xone-reiniciar-android +5 -1
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Las métricas PROPIAS de TrueForge (`AgentThreadOrchestrator.getMetrics()`), puestas al lado de
|
|
3
|
+
* las nuestras como CONTRASTE, no como sustituto.
|
|
4
|
+
*
|
|
5
|
+
* Las nuestras salen de traducir cada evento (`eventosTrueforge.ts#traducirEvento`) y son las que
|
|
6
|
+
* se enseñan y se guardan, porque son las mismas cuentas que las de deepagents. Las de la librería
|
|
7
|
+
* las lleva ella por dentro. Si las dos divergen, una de las dos cuenta mal, y hasta ahora no había
|
|
8
|
+
* forma de enterarse: esto lo apunta en la traza (`XONECODE_TRACE_TOOLS=1`) y `xonecode traza` lo
|
|
9
|
+
* dice. Puro, para poder probar la regla sin montar un turno.
|
|
10
|
+
*
|
|
11
|
+
* Se lee al final de CADA turno y es de ESE turno: el raíz se rehace desde su foto al acabar
|
|
12
|
+
* (`sesionTrueforge.ts`), así que el árbol que se mide es el de un solo turno.
|
|
13
|
+
*/
|
|
14
|
+
/** De la forma de la librería (`AgentThreadMetrics`) a la nuestra; lo que no es número no consta. */
|
|
15
|
+
export function metricasDeTrueforge(m) {
|
|
16
|
+
const n = (v) => (typeof v === "number" && Number.isFinite(v) ? v : 0);
|
|
17
|
+
const opcional = (v) => (typeof v === "number" && Number.isFinite(v) ? v : undefined);
|
|
18
|
+
const cache = opcional(m["total_cache_read_tokens"]);
|
|
19
|
+
const coste = opcional(m["total_cost_in_usd"]);
|
|
20
|
+
return {
|
|
21
|
+
entrada: n(m["total_input_tokens"]),
|
|
22
|
+
salida: n(m["total_output_tokens"]),
|
|
23
|
+
...(cache === undefined ? {} : { cache }),
|
|
24
|
+
iteraciones: n(m["iterations"]),
|
|
25
|
+
tools: n(m["total_tool_calls"]),
|
|
26
|
+
subagentes: n(m["total_sub_agents"]),
|
|
27
|
+
resumenes: n(m["total_summarizations"]),
|
|
28
|
+
...(coste === undefined ? {} : { costeUsd: coste }),
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* En qué difieren, dicho con las dos cifras. Vacío = coinciden.
|
|
33
|
+
*
|
|
34
|
+
* Los TOKENS se comparan tal cual: los dos lados suman el mismo `usage` de cada llamada, así que
|
|
35
|
+
* cualquier diferencia es una cuenta que se pierde en uno de ellos. Las LLAMADAS no se cuentan
|
|
36
|
+
* igual, y las dos diferencias están MEDIDAS contra la librería real: un hijo EXTERNO es una
|
|
37
|
+
* iteración para ella y cero llamadas para nosotros —su gasto es del producto, en la cuenta
|
|
38
|
+
* `externo`—; y una COMPACTACIÓN es una llamada para nosotros —se paga— y para ella no es una
|
|
39
|
+
* iteración, la lleva aparte en `resumenes`. Las dos se ajustan antes de comparar. Y la caché solo
|
|
40
|
+
* si la librería la trae: ausente no es cero.
|
|
41
|
+
*/
|
|
42
|
+
export function diferenciasDelContraste(nuestras, suyas, hijosExternos) {
|
|
43
|
+
const salida = [];
|
|
44
|
+
const comparar = (que, nuestra, suya) => {
|
|
45
|
+
if (nuestra !== suya)
|
|
46
|
+
salida.push(`${que}: nuestra ${nuestra}, TrueForge ${suya}`);
|
|
47
|
+
};
|
|
48
|
+
comparar("entrada", nuestras.entrada, suyas.entrada);
|
|
49
|
+
comparar("salida", nuestras.salida, suyas.salida);
|
|
50
|
+
if (suyas.cache !== undefined)
|
|
51
|
+
comparar("caché", nuestras.cache, suyas.cache);
|
|
52
|
+
comparar("llamadas", nuestras.llamadas, suyas.iteraciones - hijosExternos + suyas.resumenes);
|
|
53
|
+
return salida;
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=metricasTrueforge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metricasTrueforge.js","sourceRoot":"","sources":["../../../../src/agent/motores/trueforge/metricasTrueforge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAsBH,qGAAqG;AACrG,MAAM,UAAU,mBAAmB,CAAC,CAA0B;IAC5D,MAAM,CAAC,GAAG,CAAC,CAAU,EAAU,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACxF,MAAM,QAAQ,GAAG,CAAC,CAAU,EAAsB,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IACnH,MAAM,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAC,yBAAyB,CAAC,CAAC,CAAC;IACrD,MAAM,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC;IAC/C,OAAO;QACL,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC;QACnC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC;QACnC,GAAG,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC;QACzC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC;QAC/B,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC;QAC/B,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC;QACpC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC;QACvC,GAAG,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;KACpD,CAAC;AACJ,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,uBAAuB,CAAC,QAAwB,EAAE,KAA0B,EAAE,aAAqB;IACjH,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,MAAM,QAAQ,GAAG,CAAC,GAAW,EAAE,OAAe,EAAE,IAAY,EAAQ,EAAE;QACpE,IAAI,OAAO,KAAK,IAAI;YAAE,MAAM,CAAC,IAAI,CAAC,GAAG,GAAG,aAAa,OAAO,eAAe,IAAI,EAAE,CAAC,CAAC;IACrF,CAAC,CAAC;IACF,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;IACrD,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAClD,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS;QAAE,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;IAC9E,QAAQ,CAAC,UAAU,EAAE,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC,WAAW,GAAG,aAAa,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC;IAC7F,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* El «modelo» de un hijo EXTERNO de TrueForge: Claude Code, Codex u OpenCode detrás de un
|
|
3
|
+
* `AgentThread` normal.
|
|
4
|
+
*
|
|
5
|
+
* TrueForge exige que su factoría de hijos devuelva un `AgentThread`, y un hilo necesita un
|
|
6
|
+
* `ILLM`; el `Runnable` que deepagents acepta como `CompiledSubAgent` no tiene sitio aquí. Así que
|
|
7
|
+
* el hilo se construye como cualquier otro y lo que cambia es lo que hay detrás de su modelo: una
|
|
8
|
+
* llamada a `SubagenteExternoPort.correr()` —la MISMA integración de deepagents, con sus guardas de
|
|
9
|
+
* ruta, su política de aprobación y su consumo—, cuya respuesta final vuelve como la respuesta del
|
|
10
|
+
* hilo. El bucle agéntico vive dentro del producto, no aquí: el hilo hace UNA llamada y termina.
|
|
11
|
+
*
|
|
12
|
+
* No es un segundo `ILLM`: es un objeto con la forma de un modelo de LangChain —`stream()`— que
|
|
13
|
+
* `modeloParaTrueforge` ya sabe traducir. Un adaptador propio sería un segundo sitio donde
|
|
14
|
+
* componer los trozos que TrueForge espera.
|
|
15
|
+
*
|
|
16
|
+
* **Lo que manda TrueForge al «modelo» se IGNORA** —su identidad, su prompt de sistema, el primer
|
|
17
|
+
* mensaje—: el hijo externo recibe SUS instrucciones y SU encargo, que se capturan al crear el hilo.
|
|
18
|
+
*/
|
|
19
|
+
import { AIMessageChunk } from "@langchain/core/messages";
|
|
20
|
+
import { modeloParaTrueforge } from "./modeloLangchain.js";
|
|
21
|
+
import { textoDeFalloExterno } from "../../subagentes/subagenteExterno.js";
|
|
22
|
+
export function modeloExternoParaTrueforge(opciones) {
|
|
23
|
+
return modeloParaTrueforge({
|
|
24
|
+
nombre: "externo",
|
|
25
|
+
modelo: () => ({
|
|
26
|
+
stream: async () => {
|
|
27
|
+
const peticion = opciones.peticion();
|
|
28
|
+
const senal = opciones.senal?.();
|
|
29
|
+
let texto;
|
|
30
|
+
try {
|
|
31
|
+
texto = await opciones.puerto.correr({ ...peticion, ...(senal === undefined ? {} : { senal }) });
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
// Cancelado: no hay respuesta que dar, y el turno ya se está cerrando por su lado.
|
|
35
|
+
if (senal?.aborted === true)
|
|
36
|
+
throw error;
|
|
37
|
+
texto = textoDeFalloExterno(peticion.motor, error);
|
|
38
|
+
}
|
|
39
|
+
return (async function* () {
|
|
40
|
+
yield new AIMessageChunk({ content: texto });
|
|
41
|
+
})();
|
|
42
|
+
},
|
|
43
|
+
}),
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=modeloExterno.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"modeloExterno.js","sourceRoot":"","sources":["../../../../src/agent/motores/trueforge/modeloExterno.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAG1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,mBAAmB,EAAE,MAAM,sCAAsC,CAAC;AAE3E,MAAM,UAAU,0BAA0B,CAAC,QAM1C;IACC,OAAO,mBAAmB,CAAC;QACzB,MAAM,EAAE,SAAS;QACjB,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;YACb,MAAM,EAAE,KAAK,IAAI,EAAE;gBACjB,MAAM,QAAQ,GAAG,QAAQ,CAAC,QAAQ,EAAE,CAAC;gBACrC,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC;gBACjC,IAAI,KAAa,CAAC;gBAClB,IAAI,CAAC;oBACH,KAAK,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,QAAQ,EAAE,GAAG,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;gBACnG,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,mFAAmF;oBACnF,IAAI,KAAK,EAAE,OAAO,KAAK,IAAI;wBAAE,MAAM,KAAK,CAAC;oBACzC,KAAK,GAAG,mBAAmB,CAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;gBACrD,CAAC;gBACD,OAAO,CAAC,KAAK,SAAS,CAAC;oBACrB,MAAM,IAAI,cAAc,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;gBAC/C,CAAC,CAAC,EAAE,CAAC;YACP,CAAC;SACF,CAAC;KACH,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* El modelo de TrueForge (`ILLM`) hecho con NUESTRO modelo de LangChain.
|
|
3
|
+
*
|
|
4
|
+
* TrueForge trae su propio cliente (`VercelAILLM`), que construye el modelo desde una
|
|
5
|
+
* configuración de proveedor. No se usa, y es la decisión que hace el motor intercambiable sin
|
|
6
|
+
* que se note: nuestros modelos salen de `Modelos.paraPapel()` ya con todo lo que se les ha ido
|
|
7
|
+
* poniendo —el `user_id` de DeepSeek, el eco de su razonamiento, el tope de salida y el
|
|
8
|
+
* pensamiento adaptativo de Claude, el esfuerzo por modelo—, y reconstruirlos con la
|
|
9
|
+
* configuración de TrueForge lo perdería todo en silencio.
|
|
10
|
+
*
|
|
11
|
+
* El contrato de TrueForge habla en la forma de las chat completions de OpenAI, así que esto es
|
|
12
|
+
* una traducción en los dos sentidos: los mensajes que manda a mensajes de LangChain, y el stream
|
|
13
|
+
* de LangChain a los fragmentos que espera.
|
|
14
|
+
*
|
|
15
|
+
* **La cancelación entra por aquí**: `ILLM.create` no recibe señal, así que la de la llamada en
|
|
16
|
+
* curso se pide a `senal()` en cada `create`, y quien corre el turno la pone.
|
|
17
|
+
*/
|
|
18
|
+
import { AIMessage, HumanMessage, SystemMessage, ToolMessage } from "@langchain/core/messages";
|
|
19
|
+
import { razonamientoDe, textoDe } from "../../turno/puente.js";
|
|
20
|
+
/** El texto de un `content` de OpenAI, sea cadena o lista de partes. */
|
|
21
|
+
function textoDeContenido(contenido) {
|
|
22
|
+
if (typeof contenido === "string")
|
|
23
|
+
return contenido;
|
|
24
|
+
if (!Array.isArray(contenido))
|
|
25
|
+
return "";
|
|
26
|
+
return contenido
|
|
27
|
+
.map((p) => (typeof p === "object" && p !== null && p.type === "text" ? String(p.text) : ""))
|
|
28
|
+
.join("");
|
|
29
|
+
}
|
|
30
|
+
/** Los argumentos de una tool call, que en OpenAI viajan como cadena JSON. Rotos = `{}`. */
|
|
31
|
+
function argumentosDe(json) {
|
|
32
|
+
try {
|
|
33
|
+
const v = JSON.parse(json);
|
|
34
|
+
return typeof v === "object" && v !== null ? v : {};
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return {};
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/** Los mensajes que manda TrueForge, en mensajes de LangChain. */
|
|
41
|
+
export function aMensajesDeLangchain(mensajes) {
|
|
42
|
+
return mensajes.map((m) => {
|
|
43
|
+
switch (m.role) {
|
|
44
|
+
case "system":
|
|
45
|
+
case "developer":
|
|
46
|
+
return new SystemMessage(textoDeContenido(m.content));
|
|
47
|
+
case "assistant":
|
|
48
|
+
return new AIMessage({
|
|
49
|
+
content: textoDeContenido(m.content),
|
|
50
|
+
tool_calls: (m.tool_calls ?? []).map((t) => ({ id: t.id, name: t.function.name, args: argumentosDe(t.function.arguments), type: "tool_call" })),
|
|
51
|
+
// El razonamiento de la vuelta anterior, por si el proveedor lo exige de vuelta
|
|
52
|
+
// (DeepSeek): el eco lo repone por id de tool call, pero no se tira si viene.
|
|
53
|
+
...(m.reasoning_content === undefined ? {} : { additional_kwargs: { reasoning_content: m.reasoning_content } }),
|
|
54
|
+
});
|
|
55
|
+
case "tool":
|
|
56
|
+
return new ToolMessage({ tool_call_id: m.tool_call_id ?? "", content: textoDeContenido(m.content) });
|
|
57
|
+
default:
|
|
58
|
+
// `user` y cualquier otro rol: el contenido tal cual, que puede traer imágenes.
|
|
59
|
+
return new HumanMessage({ content: (typeof m.content === "string" || Array.isArray(m.content) ? m.content : "") });
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Un `ILLM` sobre un modelo de LangChain. `modelo` y `senal` son funciones y no valores: el modelo
|
|
65
|
+
* cambia con `/modelo` sin rehacer el hilo, y la señal es la de la llamada EN CURSO.
|
|
66
|
+
*/
|
|
67
|
+
export function modeloParaTrueforge(opciones) {
|
|
68
|
+
let secuencia = 0;
|
|
69
|
+
async function* crear(cuerpo) {
|
|
70
|
+
const base = opciones.modelo();
|
|
71
|
+
const tools = cuerpo.tools ?? [];
|
|
72
|
+
const modelo = tools.length > 0 && typeof base.bindTools === "function" ? base.bindTools(tools) : base;
|
|
73
|
+
const mensajes = aMensajesDeLangchain(cuerpo.messages);
|
|
74
|
+
const senal = opciones.senal?.();
|
|
75
|
+
const id = `xc-${++secuencia}`;
|
|
76
|
+
const creado = Math.floor(Date.now() / 1000);
|
|
77
|
+
const nombre = opciones.nombre ?? "xonecode";
|
|
78
|
+
let acumulado;
|
|
79
|
+
for await (const trozo of await modelo.stream(mensajes, senal === undefined ? {} : { signal: senal })) {
|
|
80
|
+
acumulado = acumulado === undefined ? trozo : acumulado.concat(trozo);
|
|
81
|
+
const texto = textoDe(trozo);
|
|
82
|
+
const pensado = razonamientoDe(trozo);
|
|
83
|
+
const llamadas = (trozo.tool_call_chunks ?? []).map((t, i) => ({
|
|
84
|
+
index: t.index ?? i,
|
|
85
|
+
...(t.id === undefined ? {} : { id: t.id, type: "function" }),
|
|
86
|
+
function: { ...(t.name === undefined ? {} : { name: t.name }), arguments: t.args ?? "" },
|
|
87
|
+
}));
|
|
88
|
+
if (texto === "" && pensado === "" && llamadas.length === 0)
|
|
89
|
+
continue;
|
|
90
|
+
yield {
|
|
91
|
+
id,
|
|
92
|
+
object: "chat.completion.chunk",
|
|
93
|
+
created: creado,
|
|
94
|
+
model: nombre,
|
|
95
|
+
choices: [
|
|
96
|
+
{
|
|
97
|
+
index: 0,
|
|
98
|
+
delta: {
|
|
99
|
+
role: "assistant",
|
|
100
|
+
...(texto === "" ? {} : { content: texto }),
|
|
101
|
+
...(pensado === "" ? {} : { reasoning_content: pensado }),
|
|
102
|
+
...(llamadas.length === 0 ? {} : { tool_calls: llamadas }),
|
|
103
|
+
},
|
|
104
|
+
finish_reason: null,
|
|
105
|
+
},
|
|
106
|
+
],
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
const llamadas = acumulado?.tool_calls ?? [];
|
|
110
|
+
const uso = acumulado?.usage_metadata;
|
|
111
|
+
const razonamiento = acumulado === undefined ? "" : razonamientoDe(acumulado);
|
|
112
|
+
return {
|
|
113
|
+
output: {
|
|
114
|
+
role: "assistant",
|
|
115
|
+
content: acumulado === undefined ? "" : textoDe(acumulado),
|
|
116
|
+
...(llamadas.length === 0
|
|
117
|
+
? {}
|
|
118
|
+
: {
|
|
119
|
+
tool_calls: llamadas.map((t, i) => ({
|
|
120
|
+
id: t.id ?? `${id}-${i}`,
|
|
121
|
+
type: "function",
|
|
122
|
+
function: { name: t.name, arguments: JSON.stringify(t.args ?? {}) },
|
|
123
|
+
})),
|
|
124
|
+
}),
|
|
125
|
+
...(razonamiento === "" ? {} : { reasoning_content: razonamiento }),
|
|
126
|
+
},
|
|
127
|
+
usage: {
|
|
128
|
+
input_tokens: uso?.input_tokens ?? 0,
|
|
129
|
+
output_tokens: uso?.output_tokens ?? 0,
|
|
130
|
+
total_tokens: uso?.total_tokens ?? 0,
|
|
131
|
+
...(uso?.input_token_details?.cache_read === undefined ? {} : { cache_read_tokens: uso.input_token_details.cache_read }),
|
|
132
|
+
},
|
|
133
|
+
finish_reason: llamadas.length > 0 ? "tool_calls" : "stop",
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
return {
|
|
137
|
+
create: (cuerpo) => crear(cuerpo),
|
|
138
|
+
// La compactación de contexto de TrueForge pide una respuesta entera: el mismo camino,
|
|
139
|
+
// agotado.
|
|
140
|
+
createNonStream: async (cuerpo) => {
|
|
141
|
+
const it = crear(cuerpo);
|
|
142
|
+
let r = await it.next();
|
|
143
|
+
while (!r.done)
|
|
144
|
+
r = await it.next();
|
|
145
|
+
return r.value;
|
|
146
|
+
},
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
//# sourceMappingURL=modeloLangchain.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"modeloLangchain.js","sourceRoot":"","sources":["../../../../src/agent/motores/trueforge/modeloLangchain.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAAE,SAAS,EAAkB,YAAY,EAAE,aAAa,EAAE,WAAW,EAAoB,MAAM,0BAA0B,CAAC;AAEjI,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAgBhE,wEAAwE;AACxE,SAAS,gBAAgB,CAAC,SAAkB;IAC1C,IAAI,OAAO,SAAS,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAC;IACpD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC;QAAE,OAAO,EAAE,CAAC;IACzC,OAAO,SAAS;SACb,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,IAAK,CAAuB,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAE,CAAuB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;SAC1I,IAAI,CAAC,EAAE,CAAC,CAAC;AACd,CAAC;AAED,4FAA4F;AAC5F,SAAS,YAAY,CAAC,IAAY;IAChC,IAAI,CAAC;QACH,MAAM,CAAC,GAAY,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACpC,OAAO,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,CAAE,CAA6B,CAAC,CAAC,CAAC,EAAE,CAAC;IACnF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,kEAAkE;AAClE,MAAM,UAAU,oBAAoB,CAAC,QAAkC;IACrE,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAe,EAAE;QACrC,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC;YACf,KAAK,QAAQ,CAAC;YACd,KAAK,WAAW;gBACd,OAAO,IAAI,aAAa,CAAC,gBAAgB,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;YACxD,KAAK,WAAW;gBACd,OAAO,IAAI,SAAS,CAAC;oBACnB,OAAO,EAAE,gBAAgB,CAAC,CAAC,CAAC,OAAO,CAAC;oBACpC,UAAU,EAAE,CAAC,CAAC,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,WAAoB,EAAE,CAAC,CAAC;oBACxJ,gFAAgF;oBAChF,8EAA8E;oBAC9E,GAAG,CAAC,CAAC,CAAC,iBAAiB,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,iBAAiB,EAAE,EAAE,iBAAiB,EAAE,CAAC,CAAC,iBAAiB,EAAE,EAAE,CAAC;iBAChH,CAAC,CAAC;YACL,KAAK,MAAM;gBACT,OAAO,IAAI,WAAW,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC,YAAY,IAAI,EAAE,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YACvG;gBACE,gFAAgF;gBAChF,OAAO,IAAI,YAAY,CAAC,EAAE,OAAO,EAAE,CAAC,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAU,EAAE,CAAC,CAAC;QAChI,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,QAInC;IACC,IAAI,SAAS,GAAG,CAAC,CAAC;IAElB,KAAK,SAAS,CAAC,CAAC,KAAK,CAAC,MAAkD;QAKtE,MAAM,IAAI,GAAG,QAAQ,CAAC,MAAM,EAAuB,CAAC;QACpD,MAAM,KAAK,GAAI,MAAgC,CAAC,KAAK,IAAI,EAAE,CAAC;QAC5D,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,OAAO,IAAI,CAAC,SAAS,KAAK,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACvG,MAAM,QAAQ,GAAG,oBAAoB,CAAE,MAAwC,CAAC,QAAQ,CAAC,CAAC;QAC1F,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC;QACjC,MAAM,EAAE,GAAG,MAAM,EAAE,SAAS,EAAE,CAAC;QAC/B,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;QAC7C,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,IAAI,UAAU,CAAC;QAE7C,IAAI,SAAqC,CAAC;QAC1C,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,MAAM,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;YACtG,SAAS,GAAG,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACtE,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;YAC7B,MAAM,OAAO,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;YACtC,MAAM,QAAQ,GAAG,CAAC,KAAK,CAAC,gBAAgB,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;gBAC7D,KAAK,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC;gBACnB,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,UAAmB,EAAE,CAAC;gBACtE,QAAQ,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,IAAI,IAAI,EAAE,EAAE;aACzF,CAAC,CAAC,CAAC;YACJ,IAAI,KAAK,KAAK,EAAE,IAAI,OAAO,KAAK,EAAE,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;gBAAE,SAAS;YACtE,MAAM;gBACJ,EAAE;gBACF,MAAM,EAAE,uBAAuB;gBAC/B,OAAO,EAAE,MAAM;gBACf,KAAK,EAAE,MAAM;gBACb,OAAO,EAAE;oBACP;wBACE,KAAK,EAAE,CAAC;wBACR,KAAK,EAAE;4BACL,IAAI,EAAE,WAAW;4BACjB,GAAG,CAAC,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;4BAC3C,GAAG,CAAC,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,iBAAiB,EAAE,OAAO,EAAE,CAAC;4BACzD,GAAG,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC;yBAC3D;wBACD,aAAa,EAAE,IAAI;qBACpB;iBACF;aAC6B,CAAC;QACnC,CAAC;QAED,MAAM,QAAQ,GAAG,SAAS,EAAE,UAAU,IAAI,EAAE,CAAC;QAC7C,MAAM,GAAG,GAAG,SAAS,EAAE,cAAc,CAAC;QACtC,MAAM,YAAY,GAAG,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;QAC9E,OAAO;YACL,MAAM,EAAE;gBACN,IAAI,EAAE,WAAW;gBACjB,OAAO,EAAE,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC;gBAC1D,GAAG,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC;oBACvB,CAAC,CAAC,EAAE;oBACJ,CAAC,CAAC;wBACE,UAAU,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;4BAClC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,GAAG,EAAE,IAAI,CAAC,EAAE;4BACxB,IAAI,EAAE,UAAmB;4BACzB,QAAQ,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,EAAE;yBACpE,CAAC,CAAC;qBACJ,CAAC;gBACN,GAAG,CAAC,YAAY,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,iBAAiB,EAAE,YAAY,EAAE,CAAC;aACpE;YACD,KAAK,EAAE;gBACL,YAAY,EAAE,GAAG,EAAE,YAAY,IAAI,CAAC;gBACpC,aAAa,EAAE,GAAG,EAAE,aAAa,IAAI,CAAC;gBACtC,YAAY,EAAE,GAAG,EAAE,YAAY,IAAI,CAAC;gBACpC,GAAG,CAAC,GAAG,EAAE,mBAAmB,EAAE,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,iBAAiB,EAAE,GAAG,CAAC,mBAAmB,CAAC,UAAU,EAAE,CAAC;aACzH;YACD,aAAa,EAAE,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,MAAM;SAC3B,CAAC;IACpC,CAAC;IAED,OAAO;QACL,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC;QACjC,uFAAuF;QACvF,WAAW;QACX,eAAe,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;YAChC,MAAM,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;YACzB,IAAI,CAAC,GAAG,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC;YACxB,OAAO,CAAC,CAAC,CAAC,IAAI;gBAAE,CAAC,GAAG,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC;YACpC,OAAO,CAAC,CAAC,KAAK,CAAC;QACjB,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lo que deepagents RECORTA de un resultado de tool antes de meterlo en el contexto, en TrueForge.
|
|
3
|
+
*
|
|
4
|
+
* Medido en una sesión real de MyAllXOne con la MISMA petición («lanza la app en el emulador»):
|
|
5
|
+
* TrueForge gastó 510k de entrada y deepagents 227k, con un número de tools parecido. La diferencia
|
|
6
|
+
* no estaba en el motor sino en lo que cada resultado DEJABA en el contexto: el `FilesystemMiddleware`
|
|
7
|
+
* de deepagents hace tres cosas que el adaptador de TrueForge no hacía, y un resultado que entra
|
|
8
|
+
* entero se vuelve a mandar en CADA llamada siguiente de ese hilo.
|
|
9
|
+
*
|
|
10
|
+
* 1. **Desaloja** lo que pasa de `toolTokenLimitBeforeEvict` tokens (a 4 caracteres por token) en
|
|
11
|
+
* `execute` y en las tools que no son de fichero: lo escribe en `/large_tool_results/` y al
|
|
12
|
+
* modelo le llega la ruta y un extracto de cabeza y cola. Las de fichero no se desalojan —ya
|
|
13
|
+
* paginan—, igual que en la librería.
|
|
14
|
+
* 2. **Trunca** `ls`, `glob` y `grep` por encima de 80.000 caracteres.
|
|
15
|
+
* 3. **Topa** `grep` en `grepMaxCount` coincidencias.
|
|
16
|
+
*
|
|
17
|
+
* Los VALORES son los nuestros de deepagents (`OPCIONES_BUSQUEDA_FICHEROS`), no una copia: dos
|
|
18
|
+
* motores con dos umbrales serían dos gastos que no se pueden comparar.
|
|
19
|
+
*/
|
|
20
|
+
import { OPCIONES_BUSQUEDA_FICHEROS } from "../../grafo/opcionesDeFicheros.js";
|
|
21
|
+
/** Por encima de esto `ls`/`glob`/`grep` se truncan (el `truncateIfTooLong` de deepagents). */
|
|
22
|
+
export const CARACTERES_ANTES_DE_TRUNCAR = 80_000;
|
|
23
|
+
/** Lo que se conserva al truncar: 20.000 tokens a 4 caracteres, como la librería. */
|
|
24
|
+
const CARACTERES_TRAS_TRUNCAR = 20_000 * 4;
|
|
25
|
+
export const AVISO_DE_TRUNCADO = "\n... [resultados truncados: afina el patrón o la ruta]";
|
|
26
|
+
/** Por encima de esto un resultado de `execute` o de una tool propia se desaloja del contexto. */
|
|
27
|
+
export const CARACTERES_ANTES_DE_DESALOJAR = OPCIONES_BUSQUEDA_FICHEROS.toolTokenLimitBeforeEvict * 4;
|
|
28
|
+
export const MAXIMO_DE_COINCIDENCIAS = OPCIONES_BUSQUEDA_FICHEROS.grepMaxCount;
|
|
29
|
+
export function truncarSiLargo(texto) {
|
|
30
|
+
return texto.length > CARACTERES_ANTES_DE_TRUNCAR ? texto.slice(0, CARACTERES_TRAS_TRUNCAR) + AVISO_DE_TRUNCADO : texto;
|
|
31
|
+
}
|
|
32
|
+
const numerar = (lineas, desde) => lineas.map((l, i) => `${String(desde + i).padStart(6)}\t${l.slice(0, 1000)}`).join("\n");
|
|
33
|
+
/** Cabeza y cola numeradas, con cuántas líneas se saltan en medio (`createContentPreview`). */
|
|
34
|
+
export function vistaPrevia(texto, cabeza = 5, cola = 5) {
|
|
35
|
+
const lineas = texto.split("\n");
|
|
36
|
+
if (lineas.length <= cabeza + cola)
|
|
37
|
+
return numerar(lineas, 1);
|
|
38
|
+
return [
|
|
39
|
+
numerar(lineas.slice(0, cabeza), 1),
|
|
40
|
+
`... [${lineas.length - cabeza - cola} líneas omitidas] ...`,
|
|
41
|
+
numerar(lineas.slice(-cola), lineas.length - cola + 1),
|
|
42
|
+
].join("\n");
|
|
43
|
+
}
|
|
44
|
+
let secuencia = 0;
|
|
45
|
+
/**
|
|
46
|
+
* El texto que VE el modelo: el mismo si cabe, o la ruta donde quedó y un extracto si no. Si no
|
|
47
|
+
* se puede guardar —sin carpeta de artefactos no hay dónde colgar `/large_tool_results/`, y la
|
|
48
|
+
* guarda del proyecto lo rechaza, como debe— se dice y va el extracto igual: meter el resultado
|
|
49
|
+
* entero es justo lo que esto evita.
|
|
50
|
+
*/
|
|
51
|
+
export async function desalojarSiGrande(texto, backend, forzar = false) {
|
|
52
|
+
if (!forzar && texto.length <= CARACTERES_ANTES_DE_DESALOJAR)
|
|
53
|
+
return texto;
|
|
54
|
+
const ruta = `/large_tool_results/tf-${Date.now()}-${++secuencia}.txt`;
|
|
55
|
+
let error;
|
|
56
|
+
try {
|
|
57
|
+
const r = (await backend.write(ruta, texto));
|
|
58
|
+
error = r?.error;
|
|
59
|
+
}
|
|
60
|
+
catch (e) {
|
|
61
|
+
error = e instanceof Error ? e.message : String(e);
|
|
62
|
+
}
|
|
63
|
+
const extracto = vistaPrevia(texto);
|
|
64
|
+
if (error !== undefined) {
|
|
65
|
+
return `Resultado demasiado grande (${texto.length} caracteres) y no se pudo guardar aparte (${error}). Extracto:\n\n${extracto}`;
|
|
66
|
+
}
|
|
67
|
+
return (`Resultado demasiado grande (${texto.length} caracteres): se guardó en ${ruta}. Léelo con read_file por ` +
|
|
68
|
+
`partes (offset y limit), no entero. Extracto de cabeza y cola:\n\n${extracto}`);
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* **El presupuesto de un PASO**, que el recorte de arriba no ve: cada resultado se mira solo, así
|
|
72
|
+
* que cinco `execute` en paralelo de 20.000 caracteres pasan uno a uno y juntos meten 100.000 en
|
|
73
|
+
* el contexto. Es la regla del `largeToolResponse` de TrueForge, con su umbral (10.000 tokens),
|
|
74
|
+
* portada y no montada: con los dos puestos la misma salida se procesaría dos veces.
|
|
75
|
+
*/
|
|
76
|
+
export const CARACTERES_DEL_PASO = 10_000 * 4;
|
|
77
|
+
/** Un error que haya que recortar se TRUNCA a esto en vez de desalojarse: ahí no hay nada que releer. */
|
|
78
|
+
export const CARACTERES_DE_UN_ERROR = 500;
|
|
79
|
+
const textoDelResultado = (r) => typeof r.message.content === "string" ? r.message.content : JSON.stringify(r.message.content ?? "");
|
|
80
|
+
function recortarError(r, texto) {
|
|
81
|
+
if (texto.length <= CARACTERES_DE_UN_ERROR)
|
|
82
|
+
return;
|
|
83
|
+
r.message.content = `${texto.slice(0, CARACTERES_DE_UN_ERROR)}\n... [error truncado: ${texto.length} caracteres]`;
|
|
84
|
+
r.isStructuredContent = false;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Los resultados de UN paso, dentro del presupuesto: un error ENORME se trunca, y mientras el
|
|
88
|
+
* total se pase se desalojan los mayores primero. Modifica los resultados, que es el contrato del
|
|
89
|
+
* procesador de la librería; no quita ninguno (la librería lanza si falta uno).
|
|
90
|
+
*/
|
|
91
|
+
export async function recortarPaso(resultados, backend) {
|
|
92
|
+
for (const r of resultados) {
|
|
93
|
+
const texto = textoDelResultado(r);
|
|
94
|
+
if (r.failure && texto.length > CARACTERES_ANTES_DE_DESALOJAR)
|
|
95
|
+
recortarError(r, texto);
|
|
96
|
+
}
|
|
97
|
+
let total = resultados.reduce((suma, r) => suma + textoDelResultado(r).length, 0);
|
|
98
|
+
const porTamano = [...resultados].sort((a, b) => textoDelResultado(b).length - textoDelResultado(a).length);
|
|
99
|
+
for (const r of porTamano) {
|
|
100
|
+
if (total <= CARACTERES_DEL_PASO)
|
|
101
|
+
break;
|
|
102
|
+
const antes = textoDelResultado(r);
|
|
103
|
+
if (r.failure)
|
|
104
|
+
recortarError(r, antes);
|
|
105
|
+
else {
|
|
106
|
+
r.message.content = await desalojarSiGrande(antes, backend, true);
|
|
107
|
+
r.isStructuredContent = false;
|
|
108
|
+
}
|
|
109
|
+
total -= antes.length - textoDelResultado(r).length;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
/** El procesador que TrueForge llama con todos los resultados de un paso. */
|
|
113
|
+
export function presupuestoDelPaso(backend) {
|
|
114
|
+
return {
|
|
115
|
+
process: async (resultados) => {
|
|
116
|
+
await recortarPaso(resultados, backend);
|
|
117
|
+
return {};
|
|
118
|
+
},
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=recortes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recortes.js","sourceRoot":"","sources":["../../../../src/agent/motores/trueforge/recortes.ts"],"names":[],"mappings":"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"}
|